ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2025-12-07 03:15:32
Exec Total Coverage
Lines: 4199 5229 80.3%
Functions: 294 333 88.3%
Branches: 3248 5302 61.3%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 429 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 429 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 610 void maps_init_game_vars()
67 {
68 610 viewport = {};
69 610 viewport_mode = ViewportMode::CenterAndBound;
70 610 viewport_sprite_uid = 1;
71 610 currscr_for_passive_subscr = -1;
72 610 }
73
74 static region_ids_t current_region_ids;
75
76 // Returns true if the (map, screen) is inside a scrolling region.
77 15131407 static bool is_in_scrolling_region(int map, int screen)
78 {
79 15131407 return get_region_id(map, screen) != 0;
80 }
81
82 bool is_in_screenscrolling_region(int screen)
83 {
84 if (!screenscrolling) return false;
85
86 int x = screen % 16;
87 int y = screen / 16;
88 return
89 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
90 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
91 }
92
93 8993653468 bool is_in_scrolling_region()
94 {
95 8993653468 return cur_region.screen_count > 1;
96 }
97
98 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
99 {
100
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_in_scrolling_region(map, scr)) return false;
101 1460 int region_id = get_region_id(map, region_origin_scr);
102
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
103 2232 }
104
105 251442304 bool is_in_current_region(int map, int screen)
106 {
107
2/2
✓ Branch 0 taken 1598 times.
✓ Branch 1 taken 251440706 times.
251442304 if (map != cur_map)
108 1598 return false;
109
110
3/4
✓ Branch 0 taken 251440706 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 251428493 times.
✓ Branch 3 taken 12213 times.
251440706 if (screen >= 0 && screen < 128)
111 251428493 return screen_in_current_region[screen];
112
113 12213 return screen == cur_screen;
114 251442304 }
115
116 244569190 bool is_in_current_region(int screen)
117 {
118
5/6
✓ Branch 0 taken 243453573 times.
✓ Branch 1 taken 1115617 times.
✓ Branch 2 taken 1115617 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1115612 times.
244569190 return screen == cur_screen || (screen >= 0 && screen < 128 && screen_in_current_region[screen]);
119 }
120
121 30747605 bool is_in_current_region(mapscr* scr)
122 {
123
2/2
✓ Branch 0 taken 14690 times.
✓ Branch 1 taken 30732915 times.
30747605 return scr->map == cur_map && is_in_current_region(scr->screen);
124 }
125
126 63721385 bool is_extended_height_mode()
127 {
128
2/2
✓ Branch 0 taken 63521937 times.
✓ Branch 1 taken 199448 times.
63721385 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
129 }
130
131 // Returns 0 if this is not a scrolling region.
132 42470147 int get_region_id(int map, int screen)
133 {
134
2/2
✓ Branch 0 taken 400923 times.
✓ Branch 1 taken 42069224 times.
42470147 if (screen >= 128) return 0;
135
2/2
✓ Branch 0 taken 42068100 times.
✓ Branch 1 taken 1124 times.
42069224 if (map == cur_region.map) return current_region_ids[screen];
136
137 1124 return Regions[map].get_region_id(screen);
138 42470147 }
139
140 27276802 int get_current_region_id()
141 {
142 27276802 return get_region_id(cur_map, cur_screen);
143 }
144
145 67191 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
146 {
147 67191 region.map = map;
148
149
2/2
✓ Branch 0 taken 66917 times.
✓ Branch 1 taken 274 times.
67191 if (!is_in_scrolling_region(map, screen))
150 {
151 66917 region.region_id = 0;
152 66917 region.origin_screen = screen;
153 66917 region.origin_screen_x = screen % 16;
154 66917 region.origin_screen_y = screen / 16;
155 66917 region.screen_width = 1;
156 66917 region.screen_height = 1;
157 66917 region.screen_count = 1;
158 66917 region.width = 256;
159 66917 region.height = 176;
160 66917 region_scr_dx = 0;
161 66917 region_scr_dy = 0;
162 66917 return;
163 }
164
165 274 int input_scr_x = screen % 16;
166 274 int input_scr_y = screen / 16;
167
168 // For the given screen, find the top-left corner of its region.
169 274 int origin_scr_x = input_scr_x;
170 274 int origin_scr_y = input_scr_y;
171 274 int origin_scr = screen;
172
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
173 {
174
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
175 160 origin_scr_x--;
176 }
177
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
178 {
179
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
180 234 origin_scr_y--;
181 }
182 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
183
184 // Now find the bottom-right corner.
185 274 int region_scr_right = origin_scr_x;
186
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
187 {
188
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
189 368 region_scr_right++;
190 }
191 274 int region_scr_bottom = origin_scr_y;
192
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
193 {
194
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
195 582 region_scr_bottom++;
196 }
197
198 274 region.region_id = get_region_id(map, origin_scr);
199 274 region.origin_screen = origin_scr;
200 274 region.origin_screen_x = origin_scr_x;
201 274 region.origin_screen_y = origin_scr_y;
202 274 region.screen_width = region_scr_right - origin_scr_x + 1;
203 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
204 274 region.screen_count = region.screen_width * region.screen_height;
205 274 region.width = 256 * region.screen_width;
206 274 region.height = 176 * region.screen_height;
207 274 region_scr_dx = input_scr_x - origin_scr_x;
208 274 region_scr_dy = input_scr_y - origin_scr_y;
209
210 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
211 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
212 67191 }
213
214 37503 void load_region(int dmap, int screen)
215 {
216 37503 clear_temporary_screens();
217
218 37503 int map = DMaps[dmap].map;
219 37503 current_region_ids = Regions[map].get_all_region_ids();
220
221 37503 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
222 37503 cur_screen = cur_region.origin_screen;
223 37503 world_w = cur_region.width;
224 37503 world_h = cur_region.height;
225 37503 region_scr_count = cur_region.screen_count;
226 37503 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
227 37503 region_num_rpos = cur_region.screen_count*176;
228 37503 scrolling_maze_last_solved_screen = 0;
229
230 37503 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
231
2/2
✓ Branch 0 taken 37737 times.
✓ Branch 1 taken 37503 times.
75240 for (int x = 0; x < cur_region.screen_width; x++)
232 {
233
2/2
✓ Branch 0 taken 38747 times.
✓ Branch 1 taken 37737 times.
76484 for (int y = 0; y < cur_region.screen_height; y++)
234 {
235 38747 int screen = cur_screen + x + y*16;
236
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38747 times.
38747 if (screen < 136)
237 {
238 38747 screen_in_current_region[screen] = true;
239 38747 }
240 38747 }
241 37737 }
242
243 37503 mark_current_region_handles_dirty();
244 37503 }
245
246 37503 static void prepare_current_region_handles()
247 {
248 37503 current_region_rpos_handles_dirty = false;
249 37503 current_region_screen_count = 0;
250
2/2
✓ Branch 0 taken 37851 times.
✓ Branch 1 taken 37503 times.
75354 for (int y = 0; y < cur_region.screen_height; y++)
251 {
252
2/2
✓ Branch 0 taken 38747 times.
✓ Branch 1 taken 37851 times.
76598 for (int x = 0; x < cur_region.screen_width; x++)
253 {
254 38747 int screen = cur_screen + x + y*16;
255 38747 int index_start = current_region_screen_count;
256
2/2
✓ Branch 0 taken 38747 times.
✓ Branch 1 taken 271229 times.
309976 for (int layer = 0; layer <= 6; layer++)
257 {
258 271229 mapscr* scr = get_scr_layer(screen, layer);
259
2/2
✓ Branch 0 taken 95224 times.
✓ Branch 1 taken 176005 times.
271229 if (!scr->is_valid())
260 {
261
1/2
✓ Branch 0 taken 176005 times.
✗ Branch 1 not taken.
176005 if (layer == 0) break;
262 176005 continue;
263 }
264
265 95224 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
266 95224 current_region_rpos_handles[current_region_screen_count] = {scr, screen, layer, base_rpos, 0};
267 95224 current_region_screen_count += 1;
268 95224 }
269
270 38747 int num_handles_for_scr = current_region_screen_count - index_start;
271 38747 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
272 38747 }
273 37851 }
274 37503 }
275
276 1733507840 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
277 {
278 DCHECK(!current_region_rpos_handles_dirty);
279 1733507840 return {current_region_rpos_handles, current_region_screen_count};
280 }
281
282 11474589 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
283 {
284 DCHECK(!current_region_rpos_handles_dirty);
285
2/4
✓ Branch 0 taken 11474589 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11474589 times.
11474589 if (scr == special_warp_return_scr || current_region_rpos_handles_dirty)
286 return {nullptr, 0};
287
288
2/2
✓ Branch 0 taken 65876 times.
✓ Branch 1 taken 11408713 times.
11474589 if (cur_screen >= 0x80)
289 {
290 DCHECK(scr == origin_scr);
291 65876 return {nullptr, 0};
292 }
293
294 DCHECK(is_in_current_region(scr));
295 11408713 return current_region_rpos_handles_scr[scr->screen];
296 11474589 }
297
298 37503 void mark_current_region_handles_dirty()
299 {
300 37503 current_region_rpos_handles_dirty = true;
301 37503 }
302
303 67952 void delete_temporary_screens(mapscr** screens)
304 {
305
2/2
✓ Branch 0 taken 64690304 times.
✓ Branch 1 taken 67952 times.
64758256 for (int i = 0; i < 136*7; i++)
306 {
307
2/2
✓ Branch 0 taken 267148 times.
✓ Branch 1 taken 64423156 times.
64690304 if (!screens[i])
308 64423156 continue;
309
310 267148 mapscr* scr = screens[i];
311 267148 int num_ffcs = scr->numFFC();
312
2/2
✓ Branch 0 taken 7614783 times.
✓ Branch 1 taken 267148 times.
7881931 for (int i = 0; i < num_ffcs; i++)
313 {
314 7614783 sprite* ffc = &scr->ffcs[i];
315
2/2
✓ Branch 0 taken 7611248 times.
✓ Branch 1 taken 3535 times.
7614783 if (ffc->uid)
316 3535 FFCore.release_sprite_owned_objects(ffc->uid);
317 7614783 }
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 267148 times.
267148 delete scr;
319 267148 screens[i] = NULL;
320 267148 }
321 67952 }
322
323 38675 void clear_temporary_screens()
324 {
325 38675 delete_temporary_screens(temporary_screens);
326 38675 origin_scr = nullptr;
327 38675 hero_scr = nullptr;
328 38675 }
329
330 29281 std::vector<mapscr*> take_temporary_scrs()
331 {
332
1/2
✓ Branch 0 taken 29281 times.
✗ Branch 1 not taken.
29281 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
333
2/2
✓ Branch 0 taken 29281 times.
✓ Branch 1 taken 27875512 times.
27904793 for (int i = 0; i < 136*7; i++)
334 27875512 temporary_screens[i] = nullptr;
335
336 29281 return screens;
337
1/2
✓ Branch 0 taken 29281 times.
✗ Branch 1 not taken.
29281 }
338
339 15062344 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
340 {
341 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
342
343
2/2
✓ Branch 0 taken 15015762 times.
✓ Branch 1 taken 46582 times.
15062344 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
344 15062344 viewport.w = 256;
345 15062344 viewport.h = 176 + (extended_height_mode ? 56 : 0);
346
347
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 15061984 times.
15062344 if (viewport_mode == ViewportMode::Script)
348 360 return;
349
350
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 15015822 times.
15061984 if (!is_in_scrolling_region(DMaps[dmap].map, screen))
351 {
352 15015822 viewport.x = 0;
353 15015822 viewport.y = 0;
354 15015822 }
355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
356 {
357 // Clamp the viewport to the edges of the region.
358
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
359
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
360 46162 }
361 else if (viewport_mode == ViewportMode::Center)
362 {
363 viewport.x = x - viewport.w/2;
364 viewport.y = y - viewport.h/2;
365 }
366 15062344 }
367
368 15061833 sprite* get_viewport_sprite()
369 {
370 15061833 sprite* spr = sprite::getByUID(viewport_sprite_uid);
371
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 15061827 times.
15061833 if (!spr)
372 {
373 6 viewport_sprite_uid = 1; // Hero uid.
374 6 spr = &Hero;
375 6 }
376
377 15061833 return spr;
378 }
379
380 6 void set_viewport_sprite(sprite* spr)
381 {
382 6 viewport_sprite_uid = spr->uid;
383 6 }
384
385 15032552 void update_viewport()
386 {
387 15032552 sprite* spr = get_viewport_sprite();
388 15032552 int x = spr->x + spr->txsz*16/2;
389 15032552 int y = spr->y + spr->tysz*16/2;
390 15032552 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
391 15032552 }
392
393 // TODO: should add a moveflag to sprites to configure the size of this rect (or effectively disable
394 // freezing if the rect returns is large enough). See:
395 // https://discord.com/channels/876899628556091432/1358483603700449581
396 // https://discord.com/channels/876899628556091432/1130384911983980554
397 //
398 88932866 viewport_t get_sprite_freeze_rect()
399 {
400 88932866 viewport_t freeze_rect = viewport;
401 88932866 int tile_buffer = 3;
402 88932866 freeze_rect.w += 16 * tile_buffer * 2;
403 88932866 freeze_rect.h += 16 * tile_buffer * 2;
404 88932866 freeze_rect.x -= 16 * tile_buffer;
405 88932866 freeze_rect.y -= 16 * tile_buffer;
406 88932866 return freeze_rect;
407 }
408
409 4722 mapscr* determine_hero_screen_from_coords()
410 {
411 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
412 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
413 4722 int dx = x / 256;
414 4722 int dy = y / 176;
415 4722 return get_scr(cur_screen + dx + dy * 16);
416 }
417
418 28192 bool edge_of_region(direction dir)
419 {
420
2/2
✓ Branch 0 taken 28112 times.
✓ Branch 1 taken 80 times.
28192 if (!is_in_scrolling_region()) return true;
421
422 80 int screen_x = Hero.current_screen % 16;
423 80 int screen_y = Hero.current_screen / 16;
424
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
425
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
426
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
427
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
428
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
429 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
430 28192 }
431
432 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
433 // Coordinates are clamped to the world bounds.
434 337744571 int get_screen_for_world_xy(int x, int y)
435 {
436
2/2
✓ Branch 0 taken 316605547 times.
✓ Branch 1 taken 21139024 times.
337744571 if (!is_in_scrolling_region())
437 316605547 return cur_screen;
438
439 21139024 int dx = std::clamp(x, 0, world_w - 1) / 256;
440 21139024 int dy = std::clamp(y, 0, world_h - 1) / 176;
441 21139024 int origin_screen_x = cur_screen % 16;
442 21139024 int origin_screen_y = cur_screen / 16;
443 21139024 int scr_x = origin_screen_x + dx;
444 21139024 int scr_y = origin_screen_y + dy;
445 21139024 return map_scr_xy_to_index(scr_x, scr_y);
446 337744571 }
447
448 31102071 int get_screen_for_rpos(rpos_t rpos)
449 {
450 31102071 int origin_screen_x = cur_screen % 16;
451 31102071 int origin_screen_y = cur_screen / 16;
452 31102071 int screen = static_cast<int32_t>(rpos) / 176;
453 31102071 int scr_x = origin_screen_x + screen%cur_region.screen_width;
454 31102071 int scr_y = origin_screen_y + screen/cur_region.screen_width;
455 31102071 return map_scr_xy_to_index(scr_x, scr_y);
456 }
457
458 836822289 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
459 {
460 DCHECK_LAYER_ZERO_INDEX(layer);
461
2/2
✓ Branch 0 taken 805858181 times.
✓ Branch 1 taken 30964108 times.
836822289 if (!is_in_scrolling_region())
462 805858181 return {get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
463 30964108 int screen = get_screen_for_rpos(rpos);
464 30964108 mapscr* scr = get_scr_layer(screen, layer);
465 30964108 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
466 836822289 }
467
468 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
469 // Coordinates are clamped to the world bounds.
470 3482005602 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
471 {
472 3482005602 x = std::clamp(x, 0, world_w - 1);
473 3482005602 y = std::clamp(y, 0, world_h - 1);
474
475 DCHECK_LAYER_ZERO_INDEX(layer);
476
2/2
✓ Branch 0 taken 3455663124 times.
✓ Branch 1 taken 26342478 times.
3482005602 if (!is_in_scrolling_region())
477 {
478 3455663124 int pos = COMBOPOS(x, y);
479 3455663124 return {get_scr_layer(cur_screen, layer), cur_screen, layer, (rpos_t)pos, pos};
480 }
481 26342478 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
482 3482005602 }
483
484 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
485 1926 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
486 {
487 DCHECK_LAYER_ZERO_INDEX(layer);
488 1926 return {get_scr_layer(screen, layer), screen, layer, POS_TO_RPOS(pos, screen), pos};
489 }
490
491 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
492 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
493 63137 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
494 {
495 DCHECK_LAYER_ZERO_INDEX(layer);
496 63137 return {scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
497 }
498
499 25557687 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
500 {
501 DCHECK_LAYER_ZERO_INDEX(layer);
502 25557687 rpos_handle.layer = layer;
503 25557687 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
504 25557687 }
505
506 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
507 // Coordinates are clamped to the world bounds.
508 86712 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
509 {
510 DCHECK_LAYER_ZERO_INDEX(layer);
511
512 86712 x = std::clamp(x, 0, world_w - 1);
513 86712 y = std::clamp(y, 0, world_h - 1);
514
515 86712 auto maybe_ffc_handle = getFFCAt(x, y);
516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86712 times.
86712 if (maybe_ffc_handle)
517 return maybe_ffc_handle.value();
518
519 86712 auto rpos = COMBOPOS_REGION_B(x, y);
520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86712 times.
86712 if (rpos == rpos_t::None)
521 return rpos_handle_t();
522 86712 return get_rpos_handle(rpos, layer);
523 86712 }
524
525 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
526 // directly or via zscript) only last until the next area is loaded (via loadscr).
527
528 // Returns the screen containing the (x, y) world position.
529 1551525758 mapscr* get_scr_for_world_xy(int x, int y)
530 {
531 // Quick path, but should work the same without.
532
2/2
✓ Branch 0 taken 1541086358 times.
✓ Branch 1 taken 10439400 times.
1551525758 if (!is_in_scrolling_region()) return origin_scr;
533 10439400 return get_scr(get_screen_for_world_xy(x, y));
534 1551525758 }
535
536 25986025 mapscr* get_scr_for_rpos(rpos_t rpos)
537 {
538 // Quick path, but should work the same without.
539
2/2
✓ Branch 0 taken 25848079 times.
✓ Branch 1 taken 137946 times.
25986025 if (!is_in_scrolling_region()) return origin_scr;
540 137946 return get_scr(get_screen_for_rpos(rpos));
541 25986025 }
542
543 17 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
544 {
545 17 return get_scr_layer(get_screen_for_rpos(rpos), layer);
546 }
547
548 // Note: layer=0 is the base screen, 1 is the first layer, etc.
549 2133207386 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
550 {
551 DCHECK_LAYER_ZERO_INDEX(layer);
552
2/2
✓ Branch 0 taken 2123162172 times.
✓ Branch 1 taken 10045214 times.
2133207386 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
553
2/2
✓ Branch 0 taken 708934 times.
✓ Branch 1 taken 9336280 times.
10045214 return layer == 0 ?
554 708934 get_scr_for_world_xy(x, y) :
555 9336280 get_scr_layer(get_screen_for_world_xy(x, y), layer);
556 2133207386 }
557
558 1747076271 int get_region_screen_offset(int screen)
559 {
560 1747076271 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
561 }
562
563 655240230 int get_screen_for_region_index_offset(int offset)
564 {
565 655240230 int scr_dx = offset % cur_region.screen_width;
566 655240230 int scr_dy = offset / cur_region.screen_width;
567 655240230 int screen = cur_screen + scr_dx + scr_dy*16;
568 655240230 return screen;
569 }
570
571 655056392 mapscr* get_scr_for_region_index_offset(int offset)
572 {
573 655056392 int screen = get_screen_for_region_index_offset(offset);
574 655056392 return get_scr(screen);
575 }
576
577 // The screen at (map, screen) must exist.
578 1540442314 mapscr* get_scr(int map, int screen)
579 {
580 1540442314 mapscr* scr = get_scr_maybe(map, screen);
581
1/2
✓ Branch 0 taken 1540442314 times.
✗ Branch 1 not taken.
1540442314 CHECK(scr);
582 1540442314 return scr;
583 }
584
585 841366302 mapscr* get_scr(int screen)
586 {
587 841366302 return get_scr(cur_map, screen);
588 }
589
590 // Returns null if active screen does not exist.
591 1726079784 mapscr* get_scr_maybe(int map, int screen)
592 {
593 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
594
595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1726079784 times.
1726079784 if (map == cur_map)
596 {
597
2/2
✓ Branch 0 taken 1705253810 times.
✓ Branch 1 taken 20825974 times.
1726079784 if (screen == cur_screen)
598 1705253810 return origin_scr;
599
600 20825974 int index = screen*7;
601
2/2
✓ Branch 0 taken 20802272 times.
✓ Branch 1 taken 23702 times.
20825974 if (temporary_screens[index])
602 20802272 return temporary_screens[index];
603
604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23702 times.
23702 if (screen == home_screen)
605 return special_warp_return_scr;
606 23702 }
607
608
4/6
✓ Branch 0 taken 23700 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 23700 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 23700 times.
23702 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
609 {
610 23700 int index = screen*7;
611
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23700 times.
23700 if (FFCore.ScrollingScreensAll[index])
612 23700 return FFCore.ScrollingScreensAll[index];
613 }
614
615 2 return nullptr;
616 1726079784 }
617
618 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
619 6980824401 mapscr* get_scr_layer(int map, int screen, int layer)
620 {
621 DCHECK_LAYER_ZERO_INDEX(layer);
622
2/2
✓ Branch 0 taken 6284686953 times.
✓ Branch 1 taken 696137448 times.
6980824401 if (layer == 0)
623 696137448 return get_scr(map, screen);
624
625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6284686953 times.
6284686953 if (map == cur_map)
626 {
627 6284686953 int index = screen*7 + layer;
628
2/2
✓ Branch 0 taken 6284542899 times.
✓ Branch 1 taken 144054 times.
6284686953 if (temporary_screens[index])
629 6284542899 return temporary_screens[index];
630
631
2/2
✓ Branch 0 taken 1854 times.
✓ Branch 1 taken 142200 times.
144054 if (screen == home_screen)
632 1854 return &special_warp_return_scrs[layer];
633 142200 }
634
635
1/2
✓ Branch 0 taken 142200 times.
✗ Branch 1 not taken.
142200 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
636 {
637 142200 int index = screen*7 + layer;
638
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142200 times.
142200 if (FFCore.ScrollingScreensAll[index])
639 142200 return FFCore.ScrollingScreensAll[index];
640 }
641
642 NOTREACHED();
643 6980824401 }
644
645 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
646 6559067905 mapscr* get_scr_layer(int screen, int layer)
647 {
648 6559067905 return get_scr_layer(cur_map, screen, layer);
649 }
650
651 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
652 // Return nullptr if screen is not valid.
653 418776295 mapscr* get_scr_layer_valid(int screen, int layer)
654 {
655
2/2
✓ Branch 0 taken 98849151 times.
✓ Branch 1 taken 319927144 times.
418776295 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
656 98849151 return scr;
657 319927144 return nullptr;
658 418776295 }
659
660 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
661 {
662 401 int x = get_region_relative_dx(screen);
663 401 int y = get_region_relative_dy(screen);
664
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
665 71 return nullptr;
666
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
667 return nullptr;
668
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
669 return nullptr;
670
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
671 189 return nullptr;
672
673 141 screen = screen_index_direction(screen, dir);
674
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
675 return get_scr(screen);
676
677 141 return nullptr;
678 401 }
679
680 183838 ffc_handle_t get_ffc_handle(ffc_id_t id)
681 {
682 183838 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
683 183838 uint8_t i = id % MAXFFCS;
684 183838 mapscr* scr = get_scr(screen);
685 183838 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
686 183838 return {scr, screen, id, i, ffc};
687 }
688
689 34541 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
690 {
691 34541 x += get_region_relative_dx(screen) * 256;
692 34541 y += get_region_relative_dy(screen) * 176;
693 34541 return {x, y};
694 }
695
696 1055838 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
697 {
698 1055838 int x = get_region_relative_dx(screen) * 256;
699 1055838 int y = get_region_relative_dy(screen) * 176;
700 1055838 return {x, y};
701 }
702
703 12679904370 int32_t COMBOPOS(int32_t x, int32_t y)
704 {
705 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
706 12679904370 return (y & 0xF0) + (x >> 4);
707 }
708 int32_t COMBOPOS_B(int32_t x, int32_t y)
709 {
710 if(unsigned(x) >= 256 || unsigned(y) >= 176)
711 return -1;
712 return (y & 0xF0) + (x >> 4);
713 }
714 3952241757 int32_t COMBOX(int32_t pos)
715 {
716 3952241757 return pos % 16 * 16;
717 }
718 3952241757 int32_t COMBOY(int32_t pos)
719 {
720 3952241757 return pos & 0xF0;
721 }
722
723 116915487 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
724 {
725
2/2
✓ Branch 0 taken 89757535 times.
✓ Branch 1 taken 27157952 times.
116915487 if (!is_in_scrolling_region())
726 89757535 return (rpos_t) COMBOPOS(x, y);
727
728 DCHECK(is_in_world_bounds(x, y));
729 27157952 int scr_dx = x / (16*16);
730 27157952 int scr_dy = y / (11*16);
731 27157952 int pos = COMBOPOS(x%256, y%176);
732 27157952 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
733 116915487 }
734 6955858877 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
735 {
736
2/2
✓ Branch 0 taken 1544880 times.
✓ Branch 1 taken 6954313997 times.
6955858877 if (!is_in_world_bounds(x, y))
737 1544880 return rpos_t::None;
738
739 6954313997 int scr_dx = x / (16*16);
740 6954313997 int scr_dy = y / (11*16);
741 6954313997 int pos = COMBOPOS(x%256, y%176);
742 6954313997 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
743 6955858877 }
744 27388104 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
745 {
746 27388104 int scr_index = static_cast<int32_t>(rpos) / 176;
747 27388104 int scr_dx = scr_index % cur_region.screen_width;
748 27388104 int scr_dy = scr_index / cur_region.screen_width;
749 27388104 int pos = RPOS_TO_POS(rpos);
750 27388104 int x = scr_dx*16*16 + COMBOX(pos);
751 27388104 int y = scr_dy*11*16 + COMBOY(pos);
752 27388104 return {x, y};
753 }
754 182363 int32_t COMBOX_REGION(rpos_t rpos)
755 {
756 182363 auto [x, y] = COMBOXY_REGION(rpos);
757 182363 return x;
758 }
759 134192 int32_t COMBOY_REGION(rpos_t rpos)
760 {
761 134192 auto [x, y] = COMBOXY_REGION(rpos);
762 134192 return y;
763 }
764
765 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
766 {
767 DCHECK(is_in_world_bounds(x, y));
768
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
769 70177 return (rpos_t)(x + y * 16);
770
771 int scr_dx = x / 16;
772 int scr_dy = y / 11;
773 x %= 16;
774 y %= 11;
775 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
776 70177 }
777 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
778 {
779 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
780 70632 int scr_dx = scr_index % cur_region.screen_width;
781 70632 int scr_dy = scr_index / cur_region.screen_width;
782 70632 int pos = RPOS_TO_POS(rpos);
783 70632 int x = scr_dx*16 + pos%16;
784 70632 int y = scr_dy*11 + pos/16;
785 70632 return {x, y};
786 }
787
788 92227937 int32_t mapind(int32_t map, int32_t screen)
789 {
790 92227937 return map * MAPSCRSNORMAL + screen;
791 }
792
793 FONT *get_zc_font(int index);
794
795 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
796 extern movingblock mblock2; //mblock[4]?
797 extern portal mirror_portal;
798
799 void Z_message_d(const char *format,...)
800 {
801 #ifdef _DEBUG
802 char buf[512];
803 va_list ap;
804 va_start(ap, format);
805 vsprintf(buf, format, ap);
806 va_end(ap);
807
808 al_trace("%s",buf);
809 #else
810 format=format;
811 #endif
812 }
813
814
815
816 bool checktrigger=false;
817
818 void clear_dmap(word i)
819 {
820 DMaps[i].clear();
821 }
822
823 void clear_dmaps()
824 {
825 for(int32_t i=0; i<MAXDMAPS; i++)
826 {
827 clear_dmap(i);
828 }
829 }
830
831 234956865 int32_t isdungeon(int32_t dmap, int32_t screen)
832 {
833
2/2
✓ Branch 0 taken 234909505 times.
✓ Branch 1 taken 47360 times.
234956865 if (dmap < 0) dmap = cur_dmap;
834
835 // dungeons can have any dlevel above 0
836
2/2
✓ Branch 0 taken 133862060 times.
✓ Branch 1 taken 101094805 times.
234956865 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
837 {
838
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 101084844 times.
101094805 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
839 9961 return 0;
840
841 101084844 return 1;
842 }
843
844 // dlevels that aren't dungeons are caves
845
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 133825233 times.
133862060 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
846 36827 return 1;
847
848 133825233 return 0;
849 234956865 }
850
851 43091877 int32_t isdungeon(int32_t screen)
852 {
853 43091877 return isdungeon(cur_dmap, screen);
854 }
855
856 191732905 int32_t isdungeon()
857 {
858 191732905 return isdungeon(cur_dmap, Hero.current_screen);
859 }
860
861 92430 bool canPermSecret(int32_t dmap, int32_t screen)
862 {
863
2/2
✓ Branch 0 taken 13899 times.
✓ Branch 1 taken 78531 times.
92430 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
864 }
865
866 1260391458 int32_t MAPCOMBO(int32_t x, int32_t y)
867 {
868 1260391458 x = vbound(x, 0, world_w-1);
869 1260391458 y = vbound(y, 0, world_h-1);
870 1260391458 int pos = COMBOPOS(x%256, y%176);
871 1260391458 mapscr* scr = get_scr_for_world_xy(x, y);
872 1260391458 return scr->data[pos];
873 }
874
875 //specific layers 1 to 6
876 1486667110 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
877 {
878 DCHECK(layer >= 1 && layer <= 6);
879
3/4
✓ Branch 0 taken 1466763774 times.
✓ Branch 1 taken 19903336 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1466763774 times.
1486667110 if (!is_in_world_bounds(x, y) || layer <= 0)
880 19903336 return 0;
881
882 1466763774 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
883
2/2
✓ Branch 0 taken 472762734 times.
✓ Branch 1 taken 994001040 times.
1466763774 if (!m->is_valid())
884 994001040 return 0;
885
886 472762734 int pos = COMBOPOS(x%256, y%176);
887 472762734 return m->data[pos];
888 1486667110 }
889
890 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
891 {
892 DCHECK(layer >= 1 && layer <= 6);
893 if (!is_in_world_bounds(x, y) || layer <= 0)
894 return 0;
895
896 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
897 if (!m->is_valid())
898 return 0;
899
900 int pos = COMBOPOS(x%256, y%176);
901 return m->cset[pos];
902 }
903
904 372352 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
905 {
906 DCHECK(layer >= 1 && layer <= 6);
907
2/4
✓ Branch 0 taken 372352 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 372352 times.
372352 if (!is_in_world_bounds(x, y) || layer <= 0)
908 return 0;
909
910 372352 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
911
2/2
✓ Branch 0 taken 345286 times.
✓ Branch 1 taken 27066 times.
372352 if (!m->is_valid())
912 27066 return 0;
913
914 345286 int pos = COMBOPOS(x%256, y%176);
915 345286 return m->sflag[pos];
916 372352 }
917
918 40979 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
919 {
920 DCHECK(layer >= 1 && layer <= 6);
921
2/4
✓ Branch 0 taken 40979 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40979 times.
40979 if (!is_in_world_bounds(x, y) || layer <= 0)
922 return 0;
923
924 40979 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
925
2/2
✓ Branch 0 taken 40624 times.
✓ Branch 1 taken 355 times.
40979 if (!m->is_valid())
926 355 return 0;
927
928 40624 int pos = COMBOPOS(x%256, y%176);
929 40624 return combobuf[m->data[pos]].type;
930 40979 }
931
932 371064 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
933 {
934 DCHECK(layer >= 1 && layer <= 6);
935
2/4
✓ Branch 0 taken 371064 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 371064 times.
371064 if (!is_in_world_bounds(x, y) || layer <= 0)
936 return 0;
937
938 371064 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
939
2/2
✓ Branch 0 taken 343998 times.
✓ Branch 1 taken 27066 times.
371064 if (!m->is_valid())
940 27066 return 0;
941
942 343998 int pos = COMBOPOS(x%256, y%176);
943 343998 return combobuf[m->data[pos]].flag;
944 371064 }
945
946 // True if the FFC covers x, y and is not ethereal or a changer.
947 2535876640 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
948 {
949
2/2
✓ Branch 0 taken 749496628 times.
✓ Branch 1 taken 1786380012 times.
2535876640 if (ffc_handle.data() <= 0)
950 749496628 return false;
951
952
2/2
✓ Branch 0 taken 285071207 times.
✓ Branch 1 taken 1501308805 times.
1786380012 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
953 285071207 return false;
954
955 1501308805 int32_t fx = ffc_handle.ffc->x.getInt();
956 1501308805 int32_t w = ffc_handle.scr->ffEffectWidth(ffc_handle.i) - 1;
957
2/2
✓ Branch 0 taken 1390953542 times.
✓ Branch 1 taken 110355263 times.
1501308805 if (static_cast<uint32_t>(x - fx) > static_cast<uint32_t>(w))
958 1390953542 return false;
959
960 110355263 int32_t fy = ffc_handle.ffc->y.getInt();
961 110355263 int32_t h = ffc_handle.scr->ffEffectHeight(ffc_handle.i) - 1;
962
2/2
✓ Branch 0 taken 90405363 times.
✓ Branch 1 taken 19949900 times.
110355263 if (static_cast<uint32_t>(y - fy) > static_cast<uint32_t>(h))
963 90405363 return false;
964
965 19949900 return true;
966 2535876640 }
967
968 828793636 int32_t MAPFFCOMBO(int32_t x,int32_t y)
969 {
970
2/2
✓ Branch 0 taken 11864553 times.
✓ Branch 1 taken 816929083 times.
828793636 if (auto ffc_handle = getFFCAt(x, y))
971 11864553 return ffc_handle->data();
972 816929083 return 0;
973 828793636 }
974
975 207232 int32_t MAPCSET(int32_t x, int32_t y)
976 {
977
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207232 times.
207232 if (!is_in_world_bounds(x, y))
978 return 0;
979 207232 mapscr* scr = get_scr_for_world_xy(x, y);
980 207232 int pos = COMBOPOS(x%256, y%176);
981 207232 return scr->cset[pos];
982 207232 }
983
984 86993540 int32_t MAPFLAG(int32_t x, int32_t y)
985 {
986
2/2
✓ Branch 0 taken 28464 times.
✓ Branch 1 taken 86965076 times.
86993540 if (!is_in_world_bounds(x, y))
987 28464 return 0;
988 86965076 mapscr* scr = get_scr_for_world_xy(x, y);
989 86965076 int pos = COMBOPOS(x%256, y%176);
990 86965076 return scr->sflag[pos];
991 86993540 }
992
993 95459252 int32_t COMBOTYPE(int32_t x,int32_t y)
994 {
995 95459252 int32_t b=1;
996
2/2
✓ Branch 0 taken 64651345 times.
✓ Branch 1 taken 30807907 times.
95459252 if(x&8) b<<=2;
997
2/2
✓ Branch 0 taken 60160941 times.
✓ Branch 1 taken 35298311 times.
95459252 if(y&8) b<<=1;
998
999
2/2
✓ Branch 0 taken 190910757 times.
✓ Branch 1 taken 95444015 times.
286354772 for (int32_t i = 0; i <= 1; ++i)
1000 {
1001
2/2
✓ Branch 0 taken 158594906 times.
✓ Branch 1 taken 32315851 times.
190910757 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1002 {
1003
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 158594906 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
158594906 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1004 158594906 }
1005 else
1006 {
1007
4/4
✓ Branch 0 taken 18389 times.
✓ Branch 1 taken 32297462 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 15237 times.
32315851 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1008 }
1009 190895520 }
1010
1011 95444015 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1012
5/6
✓ Branch 0 taken 3534840 times.
✓ Branch 1 taken 91909175 times.
✓ Branch 2 taken 1907859 times.
✓ Branch 3 taken 1626981 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1907859 times.
95444015 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1013 {
1014
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1907859 times.
1907859 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1015
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1907859 times.
1907859 if(cmb.usrflags&cflag3) return cNONE;
1016 1907859 }
1017 95444015 return cmb.type;
1018 95459252 }
1019
1020 58981222 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1021 {
1022 58981222 return combobuf[MAPFFCOMBO(x,y)].type;
1023 }
1024
1025 7153165 int32_t FFORCOMBO(int32_t x, int32_t y)
1026 {
1027
2/2
✓ Branch 0 taken 78428 times.
✓ Branch 1 taken 7074737 times.
7153165 if (auto ffc_handle = getFFCAt(x, y))
1028 78428 return ffc_handle->data();
1029
1030 7074737 return MAPCOMBO(x,y);
1031 7153165 }
1032
1033 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1034 {
1035 for (int32_t i = 0; i <= 1; ++i)
1036 {
1037 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1038 {
1039 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1040 }
1041 else
1042 {
1043 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1044 }
1045 }
1046 int32_t b=1;
1047
1048 if(x&8) b<<=2;
1049
1050 if(y&8) b<<=1;
1051 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1052 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1053 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1054 return cmb.type;
1055 }
1056
1057 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1058 {
1059 if (auto ffc_handle = getFFCAt(x, y))
1060 return ffc_handle->data();
1061
1062 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1063 }
1064
1065 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1066 {
1067 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1068 }
1069
1070 83355354 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1071 {
1072
2/2
✓ Branch 0 taken 28176 times.
✓ Branch 1 taken 83327178 times.
83355354 if (!is_in_world_bounds(x, y))
1073 28176 return 0;
1074
1075 83327178 mapscr* scr = get_scr_for_world_xy(x, y);
1076 83327178 int pos = COMBOPOS(x%256, y%176);
1077 83327178 return combobuf[scr->data[pos]].flag;
1078 83355354 }
1079
1080 68064571 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1081 {
1082
2/2
✓ Branch 0 taken 777663 times.
✓ Branch 1 taken 67286908 times.
68064571 if (auto ffc_handle = getFFCAt(x, y))
1083 777663 return ffc_handle->cflag();
1084
1085 67286908 return 0;
1086 68064571 }
1087
1088 1236458285 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1089 {
1090 2783424076 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1091 1546965791 return ffcIsAt(ffc_handle, x, y);
1092 });
1093 }
1094
1095 3051 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1096 {
1097
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3051 times.
3051 if (!rpos_handle.scr->is_valid()) return 0;
1098 3051 return rpos_handle.data();
1099 3051 }
1100
1101 3013066060 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1102 {
1103 DCHECK_LAYER_NEG1_INDEX(layer);
1104
2/2
✓ Branch 0 taken 22045115 times.
✓ Branch 1 taken 2991020945 times.
3013066060 if (!is_in_world_bounds(x, y)) return 0;
1105
2/2
✓ Branch 0 taken 2894073078 times.
✓ Branch 1 taken 96947867 times.
2991020945 if (layer == -1) return MAPCOMBO(x, y);
1106
1107 2894073078 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1108
2/2
✓ Branch 0 taken 1793622333 times.
✓ Branch 1 taken 1100450745 times.
2894073078 if (!rpos_handle.scr->is_valid()) return 0;
1109
1110 1100450745 return rpos_handle.data();
1111 3013066060 }
1112
1113 19157718 static void _handle_screen_load_trigger(const combined_handle_t& handle)
1114 {
1115 19157718 auto cid = handle.data();
1116 19157718 auto* cmb = &handle.combo();
1117 19157718 bool done = false;
1118 19157718 std::set<int32_t> visited;
1119
2/2
✓ Branch 0 taken 19157718 times.
✓ Branch 1 taken 19157718 times.
38315436 while(!done)
1120 {
1121
2/4
✓ Branch 0 taken 19157718 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19157718 times.
19157718 if(visited.contains(cid))
1122 {
1123 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
1124 break; // prevent infinite loop
1125 }
1126
1/2
✓ Branch 0 taken 19157718 times.
✗ Branch 1 not taken.
19157718 visited.insert(cid);
1127
1128 19157718 done = true; // don't loop again unless something changes
1129
1/2
✓ Branch 0 taken 19157718 times.
✗ Branch 1 not taken.
20043281 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
1130 885563 return trig.trigger_flags.get(TRIGFLAG_SCREENLOAD);
1131 });
1132
2/4
✓ Branch 0 taken 19157718 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19157718 times.
19157718 if(handle.data() != cid)
1133 {
1134 cid = handle.data();
1135 cmb = &handle.combo();
1136 done = false; // loop again for the new combo
1137 }
1138 }
1139 19157718 }
1140 52880 static void handle_screen_load_trigger(const screen_handles_t& screen_handles)
1141 {
1142 52880 for_every_combo_in_screen(screen_handles, _handle_screen_load_trigger);
1143 52880 }
1144 36470 void handle_region_load_trigger()
1145 {
1146
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 36318 times.
36470 if (is_in_scrolling_region())
1147 {
1148
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 19456 times.
19608 for (int screen = 0; screen < 128; screen++)
1149 {
1150
2/2
✓ Branch 0 taken 18156 times.
✓ Branch 1 taken 1300 times.
19456 if (is_in_current_region(screen))
1151 1300 handle_screen_load_trigger(create_screen_handles_one(get_scr(screen)));
1152 19456 }
1153 152 }
1154 36318 else handle_screen_load_trigger(create_screen_handles_one(get_scr(Hero.current_screen)));
1155 36470 }
1156
1157 15262 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1158 {
1159 15262 auto screen_handles = create_screen_handles_one(&scr);
1160
1161
3/4
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 14723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 539 times.
15262 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1162 {
1163 539 reveal_hidden_stairs(&scr, screen, false);
1164 539 bool do_layers = false;
1165 539 bool from_active_screen = false;
1166 539 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1167 539 }
1168
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if (flags & mLIGHTBEAM)
1169 {
1170 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1171 if (rpos_handle.ctype() == cLIGHTTARGET)
1172 {
1173 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1174 rpos_handle.increment_data();
1175 }
1176 });
1177 }
1178
1179 15262 int lvl = DMaps[cur_dmap].level;
1180 15262 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1181 15262 toggle_gswitches_load(screen_handles);
1182
1183
2/2
✓ Branch 0 taken 15170 times.
✓ Branch 1 taken 92 times.
15262 if(flags&mLOCKBLOCK) // if special stuff done before
1184 {
1185 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1186 92 }
1187
1188
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1189 {
1190 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1191 }
1192
1193
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1194 {
1195 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1196 }
1197
1198
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1199 {
1200 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1201 }
1202
1203
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSCHEST) // if special stuff done before
1204 {
1205 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1206 }
1207
1208
1209 15262 int mi = mapind(map, screen);
1210 15262 clear_xdoors_mi(screen_handles, mi);
1211 15262 clear_xstatecombos_mi(screen_handles, mi);
1212
1213 15262 handle_screen_load_trigger(screen_handles);
1214 15262 }
1215
1216 40981 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1217 {
1218
2/4
✓ Branch 0 taken 40981 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40981 times.
40981 if (map < 0 || screen < 0)
1219 return std::nullopt;
1220
1221 40981 const mapscr* source = get_canonical_scr(map, screen);
1222
2/2
✓ Branch 0 taken 39256 times.
✓ Branch 1 taken 1725 times.
40981 if (!source->is_valid())
1223 1725 return std::nullopt;
1224
1225
2/2
✓ Branch 0 taken 7936 times.
✓ Branch 1 taken 31320 times.
39256 if (layer >= 0)
1226 {
1227
2/2
✓ Branch 0 taken 23994 times.
✓ Branch 1 taken 7326 times.
31320 if (source->layermap[layer] <= 0)
1228 23994 return std::nullopt;
1229
1230 7326 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1231
1/2
✓ Branch 0 taken 7326 times.
✗ Branch 1 not taken.
7326 if (!source->is_valid())
1232 return std::nullopt;
1233 7326 }
1234
1235
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1236 15262 mapscr scr = *source;
1237
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1238
1239
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 return scr;
1240 40981 }
1241
1242 14990 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1243 {
1244
2/4
✓ Branch 0 taken 14990 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14990 times.
14990 if (map < 0 || screen < 0) return 0;
1245
1246
2/4
✓ Branch 0 taken 14990 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14990 times.
14990 if(pos>175 || pos < 0)
1247 return 0;
1248
1249 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1250 // `apply_state_changes_to_screen` checks).
1251
4/5
✓ Branch 0 taken 4736 times.
✓ Branch 1 taken 10254 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4736 times.
✓ Branch 4 taken 10254 times.
19726 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1252 4736 return s->data[pos];
1253
1254 10254 return 0;
1255 14990 }
1256
1257 // Read from the current temporary screens or, if (map, screen) is not loaded,
1258 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1259 251430839 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1260 {
1261 DCHECK_LAYER_NEG1_INDEX(layer);
1262 DCHECK(map >= 0 && screen >= 0);
1263
1264
2/2
✓ Branch 0 taken 251415849 times.
✓ Branch 1 taken 14990 times.
251430839 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1265
1266 // Screen is not in the current region, so we have to load and trigger some secrets.
1267 14990 int pos = COMBOPOS(x, y);
1268 14990 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1269 251430839 }
1270
1271 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1272 {
1273 DCHECK_LAYER_NEG1_INDEX(layer);
1274 DCHECK(map >= 0 && screen >= 0);
1275 DCHECK(is_valid_rpos(rpos));
1276
1277 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1278
1279 // Screen is not currently loaded, so we have to load and trigger some secrets.
1280 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1281 }
1282
1283 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1284 {
1285 DCHECK_LAYER_NEG1_INDEX(layer);
1286 if (!is_in_world_bounds(x, y))
1287 return 0;
1288 if (layer == -1) return MAPCSET(x, y);
1289
1290 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1291 if (!rpos_handle.scr->is_valid()) return 0;
1292
1293 return rpos_handle.cset();
1294 }
1295
1296 102306359 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1297 {
1298 DCHECK_LAYER_NEG1_INDEX(layer);
1299
3/4
✓ Branch 0 taken 5385623 times.
✓ Branch 1 taken 96920736 times.
✓ Branch 2 taken 5385623 times.
✗ Branch 3 not taken.
102306359 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1300 return 0;
1301
2/2
✓ Branch 0 taken 84194777 times.
✓ Branch 1 taken 18111582 times.
102306359 if (layer == -1) return MAPFLAG(x, y);
1302
1303 84194777 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1304
2/2
✓ Branch 0 taken 63650249 times.
✓ Branch 1 taken 20544528 times.
84194777 if (!rpos_handle.scr->is_valid()) return 0;
1305
1306 20544528 return rpos_handle.sflag();
1307 102306359 }
1308
1309 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1310 {
1311 if(layer < 1)
1312 {
1313 for (int32_t i = layer+1; i <= 1; ++i)
1314 {
1315 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1316 {
1317 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1318 }
1319 else
1320 {
1321 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1322 }
1323 }
1324 }
1325 if(layer==-1) return COMBOTYPE(x,y);
1326
1327 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1328 if (!rpos_handle.scr->is_valid()) return 0;
1329
1330 return rpos_handle.ctype();
1331 }
1332
1333 // Returns the flag for the combo at the given position.
1334 // This is also known as an "inherent flag".
1335 100479437 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1336 {
1337 DCHECK_LAYER_NEG1_INDEX(layer);
1338
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 100479149 times.
100479437 if (!is_in_world_bounds(x, y))
1339 288 return 0;
1340
2/2
✓ Branch 0 taken 84098187 times.
✓ Branch 1 taken 16380962 times.
100479149 if (layer == -1) return MAPCOMBOFLAG(x, y);
1341
1342 84098187 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1343
2/2
✓ Branch 0 taken 63668557 times.
✓ Branch 1 taken 20429630 times.
84098187 if (!rpos_handle.scr->is_valid()) return 0;
1344
1345 20429630 return rpos_handle.cflag();
1346 100479437 }
1347
1348 11727999 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1349 {
1350 DCHECK_LAYER_ZERO_INDEX(layer);
1351 11727999 auto rpos_handle = get_rpos_handle(rpos, layer);
1352
2/2
✓ Branch 0 taken 4498134 times.
✓ Branch 1 taken 7229865 times.
11727999 if (!rpos_handle.scr->is_valid()) return false;
1353
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 7225300 times.
7229865 if (rpos_handle.sflag() == flag) return true;
1354
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 7187595 times.
7225300 if (rpos_handle.cflag() == flag) return true;
1355 7187595 return false;
1356 11727999 }
1357
1358 1711513 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1359 {
1360 DCHECK(is_valid_rpos(rpos));
1361
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1711513 times.
1711513 if (rpos > region_max_rpos) return false;
1362
1363
2/2
✓ Branch 0 taken 11727999 times.
✓ Branch 1 taken 1669243 times.
13397242 for(auto q = 0; q < 7; ++q)
1364 {
1365
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11685729 times.
11727999 if(HASFLAG(flag, q, rpos))
1366 42270 return true;
1367 11685729 }
1368 1669243 return false;
1369 1711513 }
1370
1371 const char *screenstate_string[32] =
1372 {
1373 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "Some Enemies Never Return",
1374 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1375 "Boss Locked Chests", "Secrets", "Visited", "Light Beams",
1376 "All Enemies Don't Return", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1377 "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1378 };
1379
1380 36534 void eventlog_mapflags()
1381 {
1382 36534 std::ostringstream oss;
1383
1384 36534 int mi = mapind(cur_map, home_screen);
1385
1/2
✓ Branch 0 taken 36534 times.
✗ Branch 1 not taken.
36534 dword g = game->maps[mi];
1386
1387
2/4
✓ Branch 0 taken 36534 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36534 times.
✗ Branch 3 not taken.
36534 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1388
2/2
✓ Branch 0 taken 15705 times.
✓ Branch 1 taken 20829 times.
36534 if(g) // Main States
1389 {
1390 static const int order[] =
1391 {
1392 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1393 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1394 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1395 mNEVERRET, mTMPNORET, mLIGHTBEAM, mNO_ENEMIES_RETURN
1396 };
1397
1398
1/2
✓ Branch 0 taken 15705 times.
✗ Branch 1 not taken.
15705 oss << " [";
1399 15705 bool comma = false;
1400
2/2
✓ Branch 0 taken 15705 times.
✓ Branch 1 taken 251280 times.
266985 for(int fl : order)
1401 {
1402
2/2
✓ Branch 0 taken 9635 times.
✓ Branch 1 taken 241645 times.
251280 if(!(g&fl))
1403 241645 continue;
1404 9635 byte ind = byte(log2(double(fl)));
1405
2/2
✓ Branch 0 taken 2072 times.
✓ Branch 1 taken 7563 times.
9635 if(comma)
1406
1/2
✓ Branch 0 taken 2072 times.
✗ Branch 1 not taken.
2072 oss << ", ";
1407
1/2
✓ Branch 0 taken 9635 times.
✗ Branch 1 not taken.
9635 oss << screenstate_string[ind];
1408 9635 comma = true;
1409 }
1410
1/2
✓ Branch 0 taken 15705 times.
✗ Branch 1 not taken.
15705 oss << "]";
1411 15705 }
1412
3/4
✓ Branch 0 taken 36534 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 36478 times.
36534 if(game->xstates[mi]) // ExStates
1413 {
1414
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 oss << " Ex[";
1415 56 bool comma = false;
1416
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 1792 times.
1848 for(byte fl = 0; fl < 32; ++fl)
1417 {
1418
3/4
✓ Branch 0 taken 1792 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 1715 times.
1792 if(game->xstates[mi] & (1<<fl))
1419 {
1420
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 56 times.
77 if(comma)
1421
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 oss << ", ";
1422
1/2
✓ Branch 0 taken 77 times.
✗ Branch 1 not taken.
77 oss << int(fl);
1423 77 comma = true;
1424 77 }
1425 1792 }
1426
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 oss << "]";
1427 56 }
1428 { // ExDoors
1429
2/2
✓ Branch 0 taken 36534 times.
✓ Branch 1 taken 146136 times.
182670 for(int q = 0; q < 4; ++q)
1430 {
1431 146136 bool comma = false;
1432
3/4
✓ Branch 0 taken 146136 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 146134 times.
✓ Branch 3 taken 2 times.
146136 if(auto v = game->xdoors[mi][q])
1433 {
1434
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(comma)
1435 oss << ",";
1436
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else oss << " ExDoor";
1437
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 oss << "[" << dirstr[q];
1438
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 for(int fl = 0; fl < 8; ++fl)
1439
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
19 if(v & (1<<fl))
1440
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 oss << " " << int(fl);
1441
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 oss << "]";
1442 2 comma = true;
1443 2 }
1444 146136 }
1445 }
1446
2/4
✓ Branch 0 taken 36534 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36534 times.
36534 Z_eventlog("%s\n", oss.str().c_str());
1447 36534 }
1448
1449 // set specific flag
1450 5928 void setmapflag(mapscr* scr, uint32_t flag)
1451 {
1452
2/2
✓ Branch 0 taken 5915 times.
✓ Branch 1 taken 13 times.
5928 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1453 5928 int mi = mapind(cur_map, scr->screen);
1454 5928 setmapflag_mi(scr, mi, flag);
1455 5928 }
1456 57 void setmapflag_homescr(uint32_t flag)
1457 {
1458 57 int mi = mapind(cur_map, home_screen);
1459 57 setmapflag_mi(origin_scr, mi, flag);
1460 57 }
1461 2063 void setmapflag_mi(int32_t mi, uint32_t flag)
1462 {
1463 2063 byte cscr = mi&((1<<7)-1);
1464 2063 byte cmap = (mi>>7);
1465 2063 mapscr* scr = origin_scr;
1466
2/2
✓ Branch 0 taken 833 times.
✓ Branch 1 taken 1230 times.
2063 if (is_in_current_region(cmap, cscr))
1467 1230 scr = get_scr(cmap, cscr);
1468
1469 2063 setmapflag_mi(scr, mi, flag);
1470 2063 }
1471
1472 8871 static void log_state_change(int map, int screen, std::string action)
1473 {
1474
6/6
✓ Branch 0 taken 1935 times.
✓ Branch 1 taken 6936 times.
✓ Branch 2 taken 994 times.
✓ Branch 3 taken 941 times.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 642 times.
8871 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1475 7288 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1476 else
1477 1583 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1478 8871 }
1479
1480 8048 void setmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag)
1481 {
1482 8048 byte cscr = mi&((1<<7)-1);
1483 8048 byte cmap = (mi>>7);
1484
1485 8048 double temp=log2((double)flag);
1486
1/2
✓ Branch 0 taken 8048 times.
✗ Branch 1 not taken.
8048 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1487 8048 const char* replay_state_string = state_string;
1488
2/2
✓ Branch 0 taken 7528 times.
✓ Branch 1 taken 520 times.
8048 if(temp == 6) replay_state_string = "No Return";
1489
1490
3/4
✓ Branch 0 taken 8048 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1596 times.
✓ Branch 3 taken 6452 times.
8048 if (replay_is_active() && !(game->maps[mi] & flag))
1491
1/2
✓ Branch 0 taken 6452 times.
✗ Branch 1 not taken.
6452 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, replay_state_string));
1492 8048 game->maps[mi] |= flag;
1493
1/2
✓ Branch 0 taken 8048 times.
✗ Branch 1 not taken.
8048 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1494
1495
2/2
✓ Branch 0 taken 2514 times.
✓ Branch 1 taken 5534 times.
8048 if((scr->nocarry&flag)!=flag)
1496 {
1497 5534 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1498 5534 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1499
1500 5534 std::vector<int32_t> done;
1501
2/2
✓ Branch 0 taken 5421 times.
✓ Branch 1 taken 113 times.
5534 bool looped = (nmap==cmap+1 && nscr==cscr);
1502
1503
6/6
✓ Branch 0 taken 458 times.
✓ Branch 1 taken 5483 times.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 407 times.
✓ Branch 4 taken 407 times.
✓ Branch 5 taken 5534 times.
5941 while((nmap!=0) && !looped && !(nscr>=128))
1504 {
1505
3/4
✓ Branch 0 taken 407 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 191 times.
✓ Branch 3 taken 216 times.
407 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1506 {
1507
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 log_state_change(nmap, nscr, "State change carried over");
1508
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 if (replay_is_active())
1509
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, replay_state_string));
1510
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 game->maps[((nmap-1)<<7)+nscr] |= flag;
1511 216 }
1512
1513 407 cmap=nmap;
1514 407 cscr=nscr;
1515 407 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1516 407 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1517
1518
2/2
✓ Branch 0 taken 916 times.
✓ Branch 1 taken 407 times.
1323 for(auto it = done.begin(); it != done.end(); it++)
1519 {
1520
2/2
✓ Branch 0 taken 865 times.
✓ Branch 1 taken 51 times.
916 if(*it == ((nmap-1)<<7)+nscr)
1521 51 looped = true;
1522 916 }
1523
1524
1/2
✓ Branch 0 taken 407 times.
✗ Branch 1 not taken.
407 done.push_back(((nmap-1)<<7)+nscr);
1525 }
1526 5534 }
1527 8048 }
1528
1529 void unsetmapflag_home(uint32_t flag, bool anyflag)
1530 {
1531 int mi = mapind(cur_map, home_screen);
1532 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1533 }
1534
1535 void unsetmapflag(mapscr* scr, uint32_t flag, bool anyflag)
1536 {
1537 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1538 int mi = mapind(cur_map, scr->screen);
1539 unsetmapflag_mi(scr, mi, flag, anyflag);
1540 }
1541
1542 471 void unsetmapflag_mi(int32_t mi, uint32_t flag, bool anyflag)
1543 {
1544 471 byte cscr = mi&((1<<7)-1);
1545 471 byte cmap = (mi>>7);
1546 471 mapscr* scr = origin_scr;
1547
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1548 11 scr = get_scr(cmap, cscr);
1549
1550 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1551 471 }
1552
1553 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag, bool anyflag)
1554 {
1555 471 byte cscr = mi&((1<<7)-1);
1556 471 byte cmap = (mi>>7);
1557
1558
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1559 460 game->maps[mi] &= ~flag;
1560
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1561 {
1562 if(!(scr->flags4&fNOITEMRESET))
1563 game->maps[mi] &= ~flag;
1564 }
1565 11 else game->maps[mi] &= ~flag;
1566
1567 471 double temp=log2((double)flag);
1568
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1569
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1570
1571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 471 times.
471 if((scr->nocarry&flag)!=flag)
1572 {
1573 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1574 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1575
1576 471 std::vector<int32_t> done;
1577
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1578
1579
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1580 {
1581
3/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 72 times.
84 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1582 {
1583
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1584
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1585 72 }
1586
1587 84 cmap=nmap;
1588 84 cscr=nscr;
1589 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1590 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1591
1592
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 546 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1593 {
1594
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1595 6 looped = true;
1596 546 }
1597
1598
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1599 }
1600 471 }
1601 471 }
1602
1603 45474580 bool getmapflag(int32_t screen, uint32_t flag)
1604 {
1605
2/2
✓ Branch 0 taken 1162889 times.
✓ Branch 1 taken 44311691 times.
45474580 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1606 45474580 return (game->maps[mi] & flag) != 0;
1607 }
1608 6404298 bool getmapflag(mapscr* scr, uint32_t flag)
1609 {
1610
2/2
✓ Branch 0 taken 181023 times.
✓ Branch 1 taken 6223275 times.
6404298 int mi = mapind(scr->map, scr->screen >= 0x80 ? home_screen : scr->screen);
1611 6404298 return (game->maps[mi] & flag) != 0;
1612 }
1613
1614 57 void setxmapflag(int32_t screen, uint32_t flag)
1615 {
1616
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1617 57 setxmapflag_mi(mi, flag);
1618 57 }
1619 59 void setxmapflag_mi(int32_t mi, uint32_t flag)
1620 {
1621
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if(game->xstates[mi] & flag) return;
1622 59 byte cscr = mi&((1<<7)-1);
1623 59 byte cmap = (mi>>7);
1624
1625 59 byte temp=(byte)log2((double)flag);
1626
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1627
1628 59 game->xstates[mi] |= flag;
1629
1630 59 mapscr* scr = origin_scr;
1631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if (is_in_current_region(cmap, cscr))
1632 59 scr = get_scr(cmap, cscr);
1633
1634
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 if((scr->exstate_carry&flag)==flag)
1635 {
1636 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1637 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1638
1639 std::vector<int32_t> done;
1640 bool looped = (nmap==cmap+1 && nscr==cscr);
1641
1642 while((nmap!=0) && !looped && !(nscr>=128))
1643 {
1644 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1645 {
1646 log_state_change(nmap, nscr, "ExState change carried over");
1647 if (replay_is_active())
1648 replay_step_comment(fmt::format("map {} scr {} exstate {} carry", nmap, nscr, temp));
1649 game->xstates[((nmap-1)<<7)+nscr] |= flag;
1650 }
1651
1652 cmap=nmap;
1653 cscr=nscr;
1654 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1655 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1656
1657 for(auto it = done.begin(); it != done.end(); it++)
1658 {
1659 if(*it == ((nmap-1)<<7)+nscr)
1660 looped = true;
1661 }
1662
1663 done.push_back(((nmap-1)<<7)+nscr);
1664 }
1665 }
1666 59 }
1667 2 void unsetxmapflag(int32_t screen, uint32_t flag)
1668 {
1669
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1670 2 unsetxmapflag_mi(mi, flag);
1671 2 }
1672 2 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1673 {
1674
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(!(game->xstates[mi] & flag)) return;
1675 1 byte cscr = mi&((1<<7)-1);
1676 1 byte cmap = (mi>>7);
1677 1 byte temp=(byte)log2((double)flag);
1678
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1679 1 game->xstates[mi] &= ~flag;
1680
1681 1 mapscr* scr = origin_scr;
1682
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (is_in_current_region(cmap, cscr))
1683 1 scr = get_scr(cmap, cscr);
1684
1685
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if((scr->exstate_carry&flag)==flag)
1686 {
1687 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1688 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1689
1690 std::vector<int32_t> done;
1691 bool looped = (nmap==cmap+1 && nscr==cscr);
1692
1693 while((nmap!=0) && !looped && !(nscr>=128))
1694 {
1695 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1696 {
1697 log_state_change(nmap, nscr, "ExState change carried over");
1698 game->xstates[((nmap-1)<<7)+nscr] &= ~flag;
1699 }
1700
1701 cmap=nmap;
1702 cscr=nscr;
1703 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1704 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1705
1706 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1707 {
1708 if(*it == ((nmap-1)<<7)+nscr)
1709 looped = true;
1710 }
1711
1712 done.push_back(((nmap-1)<<7)+nscr);
1713 }
1714 }
1715 2 }
1716 82 bool getxmapflag(int32_t screen, uint32_t flag)
1717 {
1718
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 82 times.
82 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1719 82 return getxmapflag_mi(mi, flag);
1720 }
1721 bool getxmapflag(mapscr* scr, uint32_t flag)
1722 {
1723 int mi = mapind(scr->map, scr->screen >= 0x80 ? home_screen : scr->screen);
1724 return getxmapflag_mi(mi, flag);
1725 }
1726 487878848 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1727 {
1728 487878848 return (game->xstates[mi] & flag) != 0;
1729 }
1730
1731 4 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1732 {
1733
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1734 return;
1735
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1736 return;
1737
1738
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1739
1740 4 int cscr = mi % MAPSCRSNORMAL;
1741 4 int cmap = mi / MAPSCRSNORMAL;
1742
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (state)
1743
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1744 else
1745 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1746 4 }
1747 487878761 bool getxdoor_mi(uint mi, uint dir, uint ind)
1748 {
1749
3/6
✓ Branch 0 taken 487878761 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 487878761 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 487878761 times.
487878761 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1750 return false;
1751 487878761 return (game->xdoors[mi][dir] & (1<<ind));
1752 487878761 }
1753 9 bool getxdoor(int32_t screen, uint dir, uint ind)
1754 {
1755 9 int mi = mapind(cur_map, screen);
1756 9 return getxdoor_mi(mi,dir,ind);
1757 }
1758
1759 401 void set_doorstate_mi(uint mi, uint dir)
1760 {
1761
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1762 return;
1763 401 setmapflag_mi(mi, mDOOR_UP << dir);
1764
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1765 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1766 401 }
1767 401 void set_doorstate(uint screen, uint dir)
1768 {
1769 401 int mi = mapind(cur_map, screen);
1770 401 set_doorstate_mi(mi, dir);
1771 401 }
1772
1773 2 void set_xdoorstate_mi(uint mi, uint dir, uint ind, bool state)
1774 {
1775
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1776 return;
1777 2 setxdoor_mi(mi, dir, ind, state);
1778
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(auto di = nextscr_mi(mi, dir))
1779 2 setxdoor_mi(*di, oppositeDir[dir], ind, state);
1780 2 }
1781
1782 2 void set_xdoorstate(int32_t screen,uint dir, uint ind, bool state)
1783 {
1784 2 int mi = mapind(cur_map, screen);
1785 2 set_xdoorstate_mi(mi, dir, ind, state);
1786 2 }
1787
1788 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1789 // returns: -1 = not a warp screen
1790 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1791 {
1792 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1793
1794
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1795 return -1;
1796
1797 57 int32_t ring=scr->catchall;
1798 57 int32_t size=QMisc.warp[ring].size;
1799
1800
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1801 return -2;
1802
1803 57 int32_t index=-1;
1804
1805
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1806
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1807 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1808 57 index=i;
1809
1810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1811 return -3;
1812
1813 57 index = (index+dw)%size;
1814 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1815 57 }
1816
1817 15342762 void update_combo_cycling()
1818 {
1819 15342762 auto& combo_cache = combo_caches::can_cycle;
1820
1821 static int32_t newdata[176];
1822 static int32_t newcset[176];
1823 static bool initialized=false;
1824
1825 // Just a simple bit of optimization
1826
2/2
✓ Branch 0 taken 15342439 times.
✓ Branch 1 taken 323 times.
15342762 if(!initialized)
1827 {
1828
2/2
✓ Branch 0 taken 56848 times.
✓ Branch 1 taken 323 times.
57171 for(int32_t i=0; i<176; i++)
1829 {
1830 56848 newdata[i]=-1;
1831 56848 newcset[i]=-1;
1832 56848 }
1833
1834 323 initialized=true;
1835 323 }
1836
1837 15342762 std::set<uint16_t> restartanim;
1838
1839
1/2
✓ Branch 0 taken 15342762 times.
✗ Branch 1 not taken.
31074892 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1840 15732130 int screen = scr->screen;
1841 int32_t x;
1842
1843
2/2
✓ Branch 0 taken 2768854880 times.
✓ Branch 1 taken 15732130 times.
2784587010 for(int32_t i=0; i<176; i++)
1844 {
1845 2768854880 x=scr->data[i];
1846 2768854880 auto& mini_cmb = combo_cache.minis[x];
1847
2/2
✓ Branch 0 taken 3282224 times.
✓ Branch 1 taken 2765572656 times.
2768854880 if (!mini_cmb.can_cycle)
1848 2765572656 continue;
1849
1850 3282224 newcombo const& cmb = combobuf[x];
1851
1852 //time to restart
1853
4/4
✓ Branch 0 taken 904477 times.
✓ Branch 1 taken 2377747 times.
✓ Branch 2 taken 475770 times.
✓ Branch 3 taken 428707 times.
3282224 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1854 {
1855 428707 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1856
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428707 times.
428707 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1857 428707 newdata[i] = c;
1858
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428687 times.
428707 if(!(cmb.animflags & AF_CYCLENOCSET))
1859
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428687 times.
428687 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1860
1861
2/2
✓ Branch 0 taken 427663 times.
✓ Branch 1 taken 1044 times.
428707 if(combobuf[c].animflags & AF_CYCLE)
1862 {
1863 1044 restartanim.insert(c);
1864 1044 }
1865 428707 }
1866 3282224 }
1867
1868 15732130 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1869
2/2
✓ Branch 0 taken 2768854880 times.
✓ Branch 1 taken 15732130 times.
2784587010 for(int32_t i=0; i<176; i++)
1870 {
1871
2/2
✓ Branch 0 taken 428707 times.
✓ Branch 1 taken 2768426173 times.
2768854880 if(newdata[i]==-1)
1872 2768426173 continue;
1873
1874 428707 rpos_t rpos = (rpos_t)(rpos_base + i);
1875 428707 rpos_handle_t rpos_handle = {scr, screen, 0, rpos, i};
1876 428707 screen_combo_modify_preroutine(rpos_handle);
1877 428707 scr->data[i]=newdata[i];
1878
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428687 times.
428707 if(newcset[i]>-1)
1879 428687 scr->cset[i]=newcset[i];
1880 428707 screen_combo_modify_postroutine(rpos_handle);
1881
1882 428707 newdata[i]=-1;
1883 428707 newcset[i]=-1;
1884 428707 }
1885
1886 15732130 word c = scr->numFFC();
1887
2/2
✓ Branch 0 taken 15732130 times.
✓ Branch 1 taken 454171951 times.
469904081 for(word i=0; i<c; i++)
1888 {
1889 454171951 ffcdata& ffc = scr->ffcs[i];
1890 454171951 auto& mini_cmb = combo_cache.minis[ffc.data];
1891
2/2
✓ Branch 0 taken 7727 times.
✓ Branch 1 taken 454164224 times.
454171951 if (!mini_cmb.can_cycle)
1892 454164224 continue;
1893
1894 7727 newcombo const& cmb = combobuf[ffc.data];
1895
1896 //time to restart
1897
4/4
✓ Branch 0 taken 1181 times.
✓ Branch 1 taken 6546 times.
✓ Branch 2 taken 856 times.
✓ Branch 3 taken 325 times.
7727 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1898 {
1899 325 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1900
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
325 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1901 325 zc_ffc_set(ffc, c);
1902
2/2
✓ Branch 0 taken 217 times.
✓ Branch 1 taken 108 times.
325 if(!(cmb.animflags & AF_CYCLENOCSET))
1903
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1904
1905
2/2
✓ Branch 0 taken 265 times.
✓ Branch 1 taken 60 times.
325 if(combobuf[ffc.data].animflags & AF_CYCLE)
1906 {
1907 60 restartanim.insert(ffc.data);
1908 60 }
1909 325 }
1910 7727 }
1911
1912
2/2
✓ Branch 0 taken 8401409 times.
✓ Branch 1 taken 7330721 times.
15732130 if(get_qr(qr_CMBCYCLELAYERS))
1913 {
1914
2/2
✓ Branch 0 taken 43984326 times.
✓ Branch 1 taken 7330721 times.
51315047 for(int32_t j=1; j<=6; j++)
1915 {
1916 43984326 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1917
2/2
✓ Branch 0 taken 13895276 times.
✓ Branch 1 taken 30089050 times.
43984326 if (!layer_scr)
1918 30089050 continue;
1919
1920
2/2
✓ Branch 0 taken 2445568576 times.
✓ Branch 1 taken 13895276 times.
2459463852 for(int32_t i=0; i<176; i++)
1921 {
1922 2445568576 x=layer_scr->data[i];
1923 2445568576 auto& mini_cmb = combo_cache.minis[x];
1924
2/2
✓ Branch 0 taken 2424344 times.
✓ Branch 1 taken 2443144232 times.
2445568576 if (!mini_cmb.can_cycle)
1925 2443144232 continue;
1926
1927 2424344 newcombo const& cmb = combobuf[x];
1928
1929 //time to restart
1930
4/4
✓ Branch 0 taken 67298 times.
✓ Branch 1 taken 2357046 times.
✓ Branch 2 taken 50626 times.
✓ Branch 3 taken 16672 times.
2424344 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1931 {
1932 16672 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1933
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16672 times.
16672 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1934 16672 newdata[i] = c;
1935
2/2
✓ Branch 0 taken 644 times.
✓ Branch 1 taken 16028 times.
16672 if(!(cmb.animflags & AF_CYCLENOCSET))
1936
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16028 times.
16028 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1937 644 else newcset[i] = layer_scr->cset[i];
1938
1939
2/2
✓ Branch 0 taken 6689 times.
✓ Branch 1 taken 9983 times.
16672 if(combobuf[c].animflags & AF_CYCLE)
1940 {
1941 9983 restartanim.insert(c);
1942 9983 }
1943 16672 }
1944 2424344 }
1945
1946
2/2
✓ Branch 0 taken 2445568576 times.
✓ Branch 1 taken 13895276 times.
2459463852 for (int32_t i=0; i<176; i++)
1947 {
1948
2/2
✓ Branch 0 taken 2445551904 times.
✓ Branch 1 taken 16672 times.
2445568576 if(newdata[i]!=-1)
1949 {
1950 16672 layer_scr->data[i]=newdata[i];
1951
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16672 times.
16672 if(newcset[i]>-1)
1952 16672 layer_scr->cset[i]=newcset[i];
1953 16672 newdata[i]=-1;
1954 16672 newcset[i]=-1;
1955 16672 }
1956 2445568576 }
1957 13895276 }
1958 7330721 }
1959 15732130 });
1960
1961
2/2
✓ Branch 0 taken 15342762 times.
✓ Branch 1 taken 2661 times.
15345423 for (auto i : restartanim)
1962 {
1963 2661 combobuf[i].tile = combobuf[i].o_tile;
1964 2661 combobuf[i].cur_frame=0;
1965 2661 combobuf[i].aclk = 0;
1966
1/2
✓ Branch 0 taken 2661 times.
✗ Branch 1 not taken.
2661 combo_caches::drawing.refresh(i);
1967 }
1968 15342762 }
1969
1970 1425622635 bool iswater_type(int32_t type)
1971 {
1972 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
1973 1425622635 return (combo_class_buf[type].water!=0);
1974 }
1975
1976 bool iswater(int32_t combo)
1977 {
1978 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
1979 }
1980 5280776 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
1981 {
1982 5280776 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
1983 }
1984
1985 // (x, y) are world coordinates
1986 68217708 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
1987 {
1988
8/8
✓ Branch 0 taken 68169853 times.
✓ Branch 1 taken 47855 times.
✓ Branch 2 taken 68128006 times.
✓ Branch 3 taken 41847 times.
✓ Branch 4 taken 68058575 times.
✓ Branch 5 taken 69431 times.
✓ Branch 6 taken 63377 times.
✓ Branch 7 taken 67995198 times.
68217708 if (x<0 || x>=world_w || y<0 || y>=world_h)
1989 222510 return false;
1990
1991 67995198 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero, out_handle);
1992 68217708 }
1993
1994 148682673 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
1995 {
1996 DCHECK_LAYER_NEG1_INDEX(layer);
1997 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
1998 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
1999
2000 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
2001
2/2
✓ Branch 0 taken 108788361 times.
✓ Branch 1 taken 39894312 times.
148682673 if (get_qr(qr_SMARTER_WATER))
2002 {
2003
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 108788361 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
108788361 if (DRIEDLAKE) return 0;
2004
5/6
✓ Branch 0 taken 32450749 times.
✓ Branch 1 taken 76337612 times.
✓ Branch 2 taken 6533834 times.
✓ Branch 3 taken 25916915 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6533834 times.
108788361 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
2005 {
2006
2/2
✓ Branch 0 taken 75579153 times.
✓ Branch 1 taken 24826902 times.
100406055 for (int32_t m = layer; m <= 1; m++)
2007 {
2008
5/6
✓ Branch 0 taken 49662238 times.
✓ Branch 1 taken 25916915 times.
✓ Branch 2 taken 24834117 times.
✓ Branch 3 taken 24828121 times.
✓ Branch 4 taken 24828121 times.
✗ Branch 5 not taken.
100407274 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
2009
1/2
✓ Branch 0 taken 24828121 times.
✗ Branch 1 not taken.
49662238 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
2010 {
2011 75579153 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
2012
2/2
✓ Branch 0 taken 74489140 times.
✓ Branch 1 taken 1090013 times.
75579153 if (checkwater > 0)
2013 {
2014
2/2
✓ Branch 0 taken 1089930 times.
✓ Branch 1 taken 83 times.
1090013 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, m+1);
2015 1090013 return checkwater;
2016 }
2017 74489140 }
2018 74489140 }
2019 24826902 return 0;
2020 }
2021 else
2022 {
2023
2/2
✓ Branch 0 taken 82895090 times.
✓ Branch 1 taken 78343431 times.
161238521 for(int32_t i=(fullcheck?3:0); i>=0; i--)
2024 {
2025 82895090 int32_t tx2=((i&2)<<2)+x;
2026 82895090 int32_t ty2=((i&1)<<3)+y;
2027 82895090 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
2028 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
2029
2/2
✓ Branch 0 taken 36073 times.
✓ Branch 1 taken 82859017 times.
82895090 if (!fullcheck)
2030 {
2031 82859017 tx2 = x;
2032 82859017 ty2 = y;
2033
2/2
✓ Branch 0 taken 45330017 times.
✓ Branch 1 taken 37529000 times.
82859017 if(tx2&8) b+=2;
2034
2/2
✓ Branch 0 taken 39268876 times.
✓ Branch 1 taken 43590141 times.
82859017 if(ty2&8) b+=1;
2035 82859017 }
2036
2/2
✓ Branch 0 taken 171761171 times.
✓ Branch 1 taken 80451675 times.
252212846 for (int32_t m = layer; m <= 1; m++)
2037 {
2038 171761171 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
2039
3/6
✓ Branch 0 taken 169573668 times.
✓ Branch 1 taken 2187503 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 169573668 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
171761171 if (hero && cmb.dive_under_level && (Hero.get_standing_z_state() <= -cmb.dive_under_level))
2040 continue; // dive under this layer
2041
2042
2/2
✓ Branch 0 taken 17728431 times.
✓ Branch 1 taken 154032740 times.
171761171 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2043 {
2044
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17728431 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17728431 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
2045 {
2046 return 0;
2047 }
2048 17728431 }
2049 else
2050 {
2051
4/4
✓ Branch 0 taken 253102 times.
✓ Branch 1 taken 153779638 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 201950 times.
154032740 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
2052 {
2053 201950 return 0;
2054 }
2055 }
2056
2/2
✓ Branch 0 taken 17728431 times.
✓ Branch 1 taken 153830790 times.
171559221 if (get_qr(qr_NO_SOLID_SWIM))
2057 {
2058
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 153779638 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2241465 times.
✓ Branch 5 taken 151538173 times.
✓ Branch 6 taken 34499 times.
✓ Branch 7 taken 2206966 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 34499 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
153830790 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
2059 2241465 return 0;
2060 151589325 }
2061
3/6
✓ Branch 0 taken 497938 times.
✓ Branch 1 taken 168819818 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 497938 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
169317756 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
2062 || (hero && current_item(itype_flippers) < cmb.attribytes[0])
2063 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
2064 {
2065 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
2066 }
2067 169317756 }
2068
2069 80451675 bool found_land = false;
2070 80451675 bool found_water = false;
2071 ffc_handle_t water_ffc_handle;
2072 223215372 find_ffc([&](const ffc_handle_t& ffc_handle) {
2073
2/2
✓ Branch 0 taken 141976906 times.
✓ Branch 1 taken 786791 times.
142763697 if (ffcIsAt(ffc_handle, tx2, ty2))
2074 {
2075 786791 auto ty = ffc_handle.ctype();
2076
3/4
✓ Branch 0 taken 786791 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 592941 times.
✓ Branch 3 taken 193850 times.
786791 bool is_water_type = combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER);
2077
2078
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 786791 times.
786791 if (!is_water_type)
2079 {
2080 786791 found_land = true;
2081 786791 return true;
2082 }
2083 else
2084 {
2085 // A later FFC might be land, in which case the water will be ignored.
2086 if (!found_water)
2087 {
2088 water_ffc_handle = ffc_handle;
2089 found_water = true;
2090 }
2091 }
2092 }
2093
2094 141976906 return false;
2095 142763697 });
2096
2097
2/2
✓ Branch 0 taken 79664884 times.
✓ Branch 1 taken 786791 times.
80451675 if (found_land) return 0;
2098
2099
3/4
✓ Branch 0 taken 79641240 times.
✓ Branch 1 taken 23644 times.
✓ Branch 2 taken 79641240 times.
✗ Branch 3 not taken.
79664884 if (!i && found_water)
2100 {
2101 if (out_handle) *out_handle = water_ffc_handle;
2102 return water_ffc_handle.data();
2103 }
2104
2105 79664884 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
2106
2/2
✓ Branch 0 taken 79620390 times.
✓ Branch 1 taken 44494 times.
79664884 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
2107
7/12
✓ Branch 0 taken 79190368 times.
✓ Branch 1 taken 430022 times.
✓ Branch 2 taken 17016052 times.
✓ Branch 3 taken 62174316 times.
✓ Branch 4 taken 16191182 times.
✓ Branch 5 taken 824870 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16191182 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
79620390 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
2108 {
2109
2/2
✓ Branch 0 taken 1577 times.
✓ Branch 1 taken 1253315 times.
1254892 if (i == 0)
2110 {
2111
2/2
✓ Branch 0 taken 1253306 times.
✓ Branch 1 taken 9 times.
1253315 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(tx2, ty2, layer+1);
2112 1253315 return checkcombo;
2113 }
2114 1577 }
2115 78367075 }
2116 78343431 return 0;
2117 }
2118 }
2119 else
2120 {
2121 39894312 int32_t b = 0;
2122
2/2
✓ Branch 0 taken 20691656 times.
✓ Branch 1 taken 19202656 times.
39894312 if(x&8) b+=2;
2123
2/2
✓ Branch 0 taken 15515520 times.
✓ Branch 1 taken 24378792 times.
39894312 if(y&8) b+=1;
2124
1/2
✓ Branch 0 taken 39894312 times.
✗ Branch 1 not taken.
39894312 if (get_qr(qr_NO_SOLID_SWIM))
2125 {
2126 if (combobuf[combo].walk&(1<<b))
2127 {
2128 return 0;
2129 }
2130 }
2131
1/2
✓ Branch 0 taken 39894312 times.
✗ Branch 1 not taken.
39894312 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2132
8/8
✓ Branch 0 taken 38129219 times.
✓ Branch 1 taken 1765093 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37961274 times.
✓ Branch 4 taken 2070 times.
✓ Branch 5 taken 1777496 times.
✓ Branch 6 taken 163715 times.
✓ Branch 7 taken 165477 times.
39894312 if((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)
2133 {
2134
2/2
✓ Branch 0 taken 1942943 times.
✓ Branch 1 taken 30 times.
1942973 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, 0); //NOTE: This is only correct assuming 'combo' is 'MAPCOMBO(x,y)'
2135 1942973 return combo;
2136 }
2137 38124989 return 0;
2138 }
2139 148856323 }
2140
2141 354 bool isdamage_type(int32_t type)
2142 {
2143
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 28 times.
354 switch(type)
2144 {
2145 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2146 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2147 28 return true;
2148 }
2149 326 return false;
2150 354 }
2151
2152 2227873597 bool ispitfall_type(int32_t type)
2153 {
2154 2227873597 return combo_class_buf[type].pit != 0;
2155 }
2156
2157 2227873597 bool ispitfall(int32_t combo)
2158 {
2159 2227873597 return ispitfall_type(combobuf[combo].type);
2160 }
2161
2162 138777050 bool ispitfall(int32_t x, int32_t y)
2163 {
2164
2/2
✓ Branch 0 taken 1303540 times.
✓ Branch 1 taken 137473510 times.
138777050 if(int32_t c = MAPFFCOMBO(x,y))
2165 {
2166 1303540 return ispitfall(c) ? true : false;
2167 }
2168 137473510 int32_t c = MAPCOMBOL(2,x,y);
2169
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 137473433 times.
137473510 if(ispitfall(c)) return true;
2170
2/2
✓ Branch 0 taken 122579100 times.
✓ Branch 1 taken 14894333 times.
137473433 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2171 {
2172
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 122579100 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
122579100 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2173 122579100 }
2174 else
2175 {
2176
3/4
✓ Branch 0 taken 16383 times.
✓ Branch 1 taken 14877950 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16383 times.
14894333 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2177 }
2178 137457050 c = MAPCOMBOL(1,x,y);
2179
2/2
✓ Branch 0 taken 19968 times.
✓ Branch 1 taken 137437082 times.
137457050 if(ispitfall(c)) return true;
2180
2181
2/2
✓ Branch 0 taken 122579100 times.
✓ Branch 1 taken 14857982 times.
137437082 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2182 {
2183
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 122579100 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
122579100 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2184 122579100 }
2185 else
2186 {
2187
4/4
✓ Branch 0 taken 16533 times.
✓ Branch 1 taken 14841449 times.
✓ Branch 2 taken 12238 times.
✓ Branch 3 taken 4295 times.
14857982 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2188 }
2189 137424844 c = MAPCOMBO(x,y);
2190
2/2
✓ Branch 0 taken 59028 times.
✓ Branch 1 taken 137365816 times.
137424844 if(ispitfall(c)) return true;
2191 137365816 return false;
2192 138777050 }
2193
2194 611168969 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2195 {
2196
2/2
✓ Branch 0 taken 9485176 times.
✓ Branch 1 taken 601683793 times.
611168969 if(int32_t c = MAPFFCOMBO(x,y))
2197 {
2198
2/2
✓ Branch 0 taken 845 times.
✓ Branch 1 taken 9484331 times.
9485176 return ispitfall(c) ? c : 0;
2199 }
2200 601683793 int32_t c = MAPCOMBOL(2,x,y);
2201
2/2
✓ Branch 0 taken 1362 times.
✓ Branch 1 taken 601682431 times.
601683793 if(ispitfall(c)) return c;
2202
2203
2/2
✓ Branch 0 taken 531801349 times.
✓ Branch 1 taken 69881082 times.
601682431 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2204 {
2205
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 531801349 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
531801349 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2206 531801349 }
2207 else
2208 {
2209
3/4
✓ Branch 0 taken 81755 times.
✓ Branch 1 taken 69799327 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 81755 times.
69881082 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2210 }
2211 601600676 c = MAPCOMBOL(1,x,y);
2212
2/2
✓ Branch 0 taken 25192 times.
✓ Branch 1 taken 601575484 times.
601600676 if(ispitfall(c)) return c;
2213
2214
2/2
✓ Branch 0 taken 531801349 times.
✓ Branch 1 taken 69774135 times.
601575484 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2215 {
2216
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 531801349 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
531801349 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2217 531801349 }
2218 else
2219 {
2220
4/4
✓ Branch 0 taken 171385 times.
✓ Branch 1 taken 69602750 times.
✓ Branch 2 taken 130757 times.
✓ Branch 3 taken 40628 times.
69774135 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2221 }
2222 601444727 c = MAPCOMBO(x,y);
2223
2/2
✓ Branch 0 taken 200737 times.
✓ Branch 1 taken 601243990 times.
601444727 if(ispitfall(c)) return c;
2224 601243990 return 0;
2225 611168969 }
2226 99 optional<combined_handle_t> get_pitfall_handle(int32_t x, int32_t y) //Return the highest-layer active pit combo handle at the given position
2227 {
2228
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 98 times.
99 if(int32_t c = MAPFFCOMBO(x,y))
2229 {
2230
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 return ispitfall(c) ? getFFCAt(x,y) : nullopt;
2231 }
2232 98 int32_t c = MAPCOMBOL(2,x,y);
2233
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 97 times.
98 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 2);
2234
2235
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 91 times.
97 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2236 {
2237
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1))
2238 return nullopt;
2239 6 }
2240 else
2241 {
2242
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
91 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1))
2243 return nullopt;
2244 }
2245 97 c = MAPCOMBOL(1,x,y);
2246
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 85 times.
97 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 1);
2247
2248
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 79 times.
85 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2249 {
2250
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0))
2251 return nullopt;
2252 6 }
2253 else
2254 {
2255
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 79 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
79 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0))
2256 return nullopt;
2257 }
2258 85 c = MAPCOMBO(x,y);
2259
1/2
✓ Branch 0 taken 85 times.
✗ Branch 1 not taken.
85 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 0);
2260 return nullopt;
2261 99 }
2262 11918937 bool check_icy(newcombo const& cmb, int type)
2263 {
2264
2/2
✓ Branch 0 taken 11918772 times.
✓ Branch 1 taken 165 times.
11918937 if(cmb.type != cICY)
2265 11918772 return false;
2266
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 165 times.
165 switch(type)
2267 {
2268 case ICY_BLOCK:
2269 return cmb.usrflags&cflag1;
2270 case ICY_PLAYER:
2271 165 return cmb.usrflags&cflag2;
2272 }
2273 return false;
2274 11918937 }
2275 3978929 int get_icy(int x, int y, int type)
2276 {
2277 3978929 int32_t c = MAPCOMBOL(2,x,y);
2278
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3978929 times.
3978929 if(check_icy(combobuf[c], type)) return c;
2279
2280 3978929 int screen = get_screen_for_world_xy(x, y);
2281
2282 3978929 mapscr* scr = get_scr_layer_valid(screen, 2);
2283
2/2
✓ Branch 0 taken 33173 times.
✓ Branch 1 taken 3945756 times.
3978929 if (scr)
2284 {
2285
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 3945240 times.
3945756 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2286 {
2287
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
516 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2288 516 }
2289 else
2290 {
2291
3/4
✓ Branch 0 taken 6663 times.
✓ Branch 1 taken 3938577 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6663 times.
3945240 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2292 }
2293 3939093 }
2294 3972266 c = MAPCOMBOL(1,x,y);
2295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3972266 times.
3972266 if(check_icy(combobuf[c], type)) return c;
2296
2297 3972266 scr = get_scr_layer_valid(screen, 1);
2298
2/2
✓ Branch 0 taken 15312 times.
✓ Branch 1 taken 3956954 times.
3972266 if (scr)
2299 {
2300
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 3955020 times.
3956954 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2301 {
2302
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1934 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1934 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2303 1934 }
2304 else
2305 {
2306
3/4
✓ Branch 0 taken 4689 times.
✓ Branch 1 taken 3950331 times.
✓ Branch 2 taken 4689 times.
✗ Branch 3 not taken.
3955020 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2307 }
2308 3952265 }
2309 3967577 c = MAPCOMBO(x,y);
2310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3967577 times.
3967577 if(check_icy(combobuf[c], type)) return c;
2311 3967577 return 0;
2312 3978929 }
2313
2314 13242479 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2315 {
2316
8/8
✓ Branch 0 taken 13235681 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 13226815 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 13215183 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 434700 times.
✓ Branch 7 taken 12780483 times.
13242479 if(x<0 || x>=world_w || y<0 || y>=world_h)
2317 461996 return false;
2318
2319 12780483 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2320
2/4
✓ Branch 0 taken 12780483 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12780483 times.
12780483 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2321 return true;
2322
2323 12780483 change_rpos_handle_layer(rpos_handle, 1);
2324
2/2
✓ Branch 0 taken 7552834 times.
✓ Branch 1 taken 5227649 times.
12780483 if (rpos_handle.scr->is_valid())
2325
3/4
✓ Branch 0 taken 5227649 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3279 times.
✓ Branch 3 taken 5224370 times.
5227649 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2326 3279 return true;
2327
2328 12777204 change_rpos_handle_layer(rpos_handle, 2);
2329
2/2
✓ Branch 0 taken 10836636 times.
✓ Branch 1 taken 1940568 times.
12777204 if (rpos_handle.scr->is_valid())
2330
3/4
✓ Branch 0 taken 1940568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 1940487 times.
1940568 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2331 81 return true;
2332
2333 12777123 return false;
2334 13242479 }
2335
2336 6685422 bool isSVLadder(int32_t x, int32_t y)
2337 {
2338 6685422 return checkSV(x, y, mfSIDEVIEWLADDER);
2339 }
2340
2341 6557057 bool isSVPlatform(int32_t x, int32_t y)
2342 {
2343 6557057 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2344 }
2345
2346 6557057 bool checkSVLadderPlatform(int32_t x, int32_t y)
2347 {
2348
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6557057 times.
✓ Branch 2 taken 6555219 times.
✓ Branch 3 taken 1838 times.
6557057 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2349 }
2350
2351 4185 bool isstepable(int32_t combo) //can use ladder on it
2352 {
2353
2/2
✓ Branch 0 taken 4179 times.
✓ Branch 1 taken 6 times.
4185 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2354
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2355 {
2356 if(combobuf[combo].usrflags&cflag4)
2357 {
2358 int32_t ldrid = current_item_id(itype_ladder);
2359 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2360 }
2361 }
2362 6 return false;
2363 4185 }
2364
2365 33016 bool isHSGrabbable(newcombo const& cmb)
2366 {
2367
2/2
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 32639 times.
33016 if(cmb.type == cHSGRAB) return true;
2368 32639 return cmb.genflags & cflag1;
2369 33016 }
2370
2371 954 bool isSwitchHookable(newcombo const& cmb)
2372 {
2373
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2374 822 return cmb.genflags & cflag2;
2375 954 }
2376
2377 62207 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2378 {
2379 62207 rpos_t cpos = rpos_t::None;
2380
2/2
✓ Branch 0 taken 65056 times.
✓ Branch 1 taken 127263 times.
62207 if(out_rpos)
2381 {
2382 127263 int32_t id = MAPCOMBO2(layer-1,x,y);
2383
2/2
✓ Branch 0 taken 29204 times.
✓ Branch 1 taken 98059 times.
127263 if(id > 0)
2384 {
2385 98059 newcombo const& cmb = combobuf[id];
2386
4/4
✓ Branch 0 taken 32974 times.
✓ Branch 1 taken 65085 times.
✓ Branch 2 taken 32528 times.
✓ Branch 3 taken 32557 times.
98059 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2387 33003 }
2388 62207 }
2389
2390 127263 ffcdata* ffc = nullptr;
2391
4/4
✓ Branch 0 taken 28531 times.
✓ Branch 1 taken 98732 times.
✓ Branch 2 taken 24996 times.
✓ Branch 3 taken 3535 times.
127263 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2392 {
2393 10645 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2394
2/2
✓ Branch 0 taken 6995 times.
✓ Branch 1 taken 115 times.
7110 if (ffcIsAt(ffc_handle, x, y))
2395 {
2396 115 auto& cmb = ffc_handle.combo();
2397
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 37 times.
✓ Branch 3 taken 36 times.
115 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2398 {
2399 79 ffc = ffc_handle.ffc;
2400 79 return false;
2401 }
2402 36 }
2403 7031 return true;
2404 7038 });
2405 3535 }
2406
2407
4/4
✓ Branch 0 taken 62207 times.
✓ Branch 1 taken 65056 times.
✓ Branch 2 taken 446 times.
✓ Branch 3 taken 61761 times.
127263 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2408
4/4
✓ Branch 0 taken 28531 times.
✓ Branch 1 taken 98732 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 28524 times.
127263 if (out_ffc && ffc) *out_ffc = ffc;
2409
2/2
✓ Branch 0 taken 65502 times.
✓ Branch 1 taken 61761 times.
127263 return (cpos != rpos_t::None || ffc);
2410 }
2411
2412 5199 bool ishookshottable(int32_t bx, int32_t by)
2413 {
2414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5199 times.
5199 if(!_walkflag(bx,by,1))
2415 return true;
2416
2417
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5191 times.
5199 if (collide_object(bx, by, 1, 1))
2418 8 return false;
2419
2420 5191 bool ret = true;
2421
2/2
✓ Branch 0 taken 15573 times.
✓ Branch 1 taken 1904 times.
17477 for(int32_t i=2; i>=0; i--)
2422 {
2423 15573 int32_t c = MAPCOMBO2(i-1,bx,by);
2424 15573 int32_t t = combobuf[c].type;
2425
2426
6/6
✓ Branch 0 taken 5191 times.
✓ Branch 1 taken 10382 times.
✓ Branch 2 taken 3857 times.
✓ Branch 3 taken 1334 times.
✓ Branch 4 taken 1904 times.
✓ Branch 5 taken 1953 times.
15573 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2427
2428
3/4
✓ Branch 0 taken 11333 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
13239 bool dried = (iswater_type(t) && DRIEDLAKE);
2429
2430 12286 int32_t b=1;
2431
2432
2/2
✓ Branch 0 taken 6112 times.
✓ Branch 1 taken 6174 times.
12286 if(bx&8) b<<=2;
2433
2434
2/2
✓ Branch 0 taken 3853 times.
✓ Branch 1 taken 8433 times.
12286 if(by&8) b<<=1;
2435
2436
7/8
✓ Branch 0 taken 2098 times.
✓ Branch 1 taken 10188 times.
✓ Branch 2 taken 2098 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 983 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 908 times.
12286 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2437 908 ret = false;
2438 12286 }
2439
2440 1904 return ret;
2441 5199 }
2442
2443 11104 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2444 {
2445
4/4
✓ Branch 0 taken 10526 times.
✓ Branch 1 taken 578 times.
✓ Branch 2 taken 10526 times.
✓ Branch 3 taken 578 times.
11104 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2446 {
2447 578 int pos = COMBOPOS(s->stairx,s->stairy);
2448 578 s->data[pos] = s->secretcombo[sSTAIRS];
2449 578 s->cset[pos] = s->secretcset[sSTAIRS];
2450 578 s->sflag[pos] = s->secretflag[sSTAIRS];
2451
2452
2/2
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 323 times.
578 if (redraw)
2453 {
2454 765 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2455 765 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2456 255 }
2457
2458 578 return true;
2459 }
2460
2461 10526 return false;
2462 11104 }
2463
2464 52880 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2465 {
2466 DCHECK(base_scr->is_valid());
2467
2468 52880 screen_handles_t screen_handles{};
2469 52880 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2470 52880 return screen_handles;
2471 }
2472
2473 58516795 screen_handles_t create_screen_handles(mapscr* base_scr)
2474 {
2475 DCHECK(get_scr(base_scr->screen) == base_scr);
2476 DCHECK(base_scr->is_valid());
2477
2478 58516795 int screen = base_scr->screen;
2479 screen_handles_t screen_handles;
2480 58516795 screen_handles[0] = {base_scr, base_scr, screen, 0};
2481
2/2
✓ Branch 0 taken 351100770 times.
✓ Branch 1 taken 58516795 times.
409617565 for (int i = 1; i <= 6; i++)
2482 351100770 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2483 58516795 return screen_handles;
2484 }
2485
2486 113471 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2487 {
2488 113471 mapscr* scr = screen_handles[0].base_scr;
2489 113471 bool didit=false;
2490
2491
2/2
✓ Branch 0 taken 113471 times.
✓ Branch 1 taken 19970896 times.
20084367 for(int32_t i=0; i<176; i++)
2492 {
2493 19970896 newcombo const& cmb = combobuf[scr->data[i]];
2494
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 19970570 times.
19970896 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2495
4/4
✓ Branch 0 taken 19968994 times.
✓ Branch 1 taken 1576 times.
✓ Branch 2 taken 1134 times.
✓ Branch 3 taken 19967860 times.
19970570 if((cmb.type == what1) || (cmb.type== what2))
2496 {
2497 2710 scr->data[i]++;
2498 2710 didit=true;
2499 2710 }
2500 19970570 }
2501
2502
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 113379 times.
113471 if (do_layers)
2503 {
2504
2/2
✓ Branch 0 taken 680274 times.
✓ Branch 1 taken 113379 times.
793653 for(int32_t j=1; j<=6; j++)
2505 {
2506 680274 mapscr* layer_scr = screen_handles[j].scr;
2507
2/2
✓ Branch 0 taken 195881 times.
✓ Branch 1 taken 484393 times.
680274 if (!layer_scr) continue;
2508
2509
2/2
✓ Branch 0 taken 34475056 times.
✓ Branch 1 taken 195881 times.
34670937 for(int32_t i=0; i<176; i++)
2510 {
2511 34475056 newcombo const& cmb = combobuf[layer_scr->data[i]];
2512
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34475056 times.
34475056 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2513
4/4
✓ Branch 0 taken 34474741 times.
✓ Branch 1 taken 315 times.
✓ Branch 2 taken 319 times.
✓ Branch 3 taken 34474422 times.
34475056 if((cmb.type== what1) || (cmb.type== what2))
2514 {
2515 634 layer_scr->data[i]++;
2516 634 didit=true;
2517 634 }
2518 34475056 }
2519 195881 }
2520 113379 }
2521
2522 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2523
3/4
✓ Branch 0 taken 27675 times.
✓ Branch 1 taken 85796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27675 times.
113471 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2524 {
2525 27675 word c = scr->numFFC();
2526
2/2
✓ Branch 0 taken 80883 times.
✓ Branch 1 taken 27675 times.
108558 for(word i=0; i<c; i++)
2527 {
2528 80883 ffcdata* ffc = &scr->ffcs[i];
2529 80883 newcombo const& cmb = combobuf[ffc->data];
2530
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80883 times.
80883 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2531
2/4
✓ Branch 0 taken 80883 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 80883 times.
80883 if((cmb.type== what1) || (cmb.type== what2))
2532 {
2533 zc_ffc_modify(*ffc, 1);
2534 didit=true;
2535 }
2536 80883 }
2537 27675 }
2538
2539 113471 return didit;
2540 }
2541
2542 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2543 {
2544 14 int screen = screen_handles[0].screen;
2545
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2546 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2547 }
2548 487878766 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2549 {
2550 487878766 bool didit=false;
2551
2/2
✓ Branch 0 taken 487837805 times.
✓ Branch 1 taken 40961 times.
487878766 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2552
2553 40961 mapscr* s = screen_handles[0].base_scr;
2554 40961 int screen = s->screen;
2555 40961 bool is_active_screen = is_in_current_region(s);
2556
2557 34122305 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2558
4/4
✓ Branch 0 taken 49456 times.
✓ Branch 1 taken 34031888 times.
✓ Branch 2 taken 1891 times.
✓ Branch 3 taken 34079453 times.
34081344 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2559 1891 didit = true;
2560
2/2
✓ Branch 0 taken 64673 times.
✓ Branch 1 taken 34014780 times.
34079453 else switch (rpos_handle.ctype())
2561 {
2562 case cLOCKBLOCK: case cLOCKBLOCK2:
2563 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2564 case cCHEST: case cCHEST2:
2565 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2566 case cBOSSCHEST: case cBOSSCHEST2:
2567 {
2568 64673 auto& cmb = rpos_handle.combo();
2569
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 2614 times.
64673 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2570
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.attribytes[5] == xflag)
2571 {
2572 29 rpos_handle.increment_data();
2573 29 didit=true;
2574 29 }
2575 62059 break;
2576 }
2577 }
2578 34081344 });
2579
2580
4/4
✓ Branch 0 taken 40889 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 31269 times.
✓ Branch 3 taken 9620 times.
40961 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2581 {
2582 31269 word c = s->numFFC();
2583 31269 int screen_index_offset = get_region_screen_offset(screen);
2584
2/2
✓ Branch 0 taken 65746 times.
✓ Branch 1 taken 31269 times.
97015 for (uint8_t i = 0; i < c; i++)
2585 {
2586 65746 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2587 65746 auto& cmb = ffc_handle.combo();
2588
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 65746 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 65730 times.
65746 if(triggers && force_ex_trigger_any(ffc_handle, xflag))
2589 16 didit = true;
2590
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65730 times.
65730 else switch(cmb.type)
2591 {
2592 case cLOCKBLOCK: case cLOCKBLOCK2:
2593 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2594 case cCHEST: case cCHEST2:
2595 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2596 case cBOSSCHEST: case cBOSSCHEST2:
2597 {
2598 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2599 if(cmb.attribytes[5] == xflag)
2600 {
2601 zc_ffc_modify(*ffc_handle.ffc, 1);
2602 didit=true;
2603 }
2604 break;
2605 }
2606 }
2607 65746 }
2608 31269 }
2609
2610 40961 return didit;
2611 487878766 }
2612
2613 15193108 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2614 {
2615 15193108 int screen = screen_handles[0].screen;
2616
2/2
✓ Branch 0 taken 387330 times.
✓ Branch 1 taken 14805778 times.
15193108 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2617 15193108 clear_xstatecombos_mi(screen_handles, mi, triggers);
2618 15193108 }
2619
2620 15246211 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2621 {
2622
2/2
✓ Branch 0 taken 487878752 times.
✓ Branch 1 taken 15246211 times.
503124963 for (int q = 0; q < 32; ++q)
2623 {
2624 487878752 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2625 487878752 }
2626 15246211 }
2627
2628 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2629 {
2630 int screen = screen_handles[0].screen;
2631 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2632 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2633 }
2634 487878752 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2635 {
2636 487878752 bool didit=false;
2637
2/2
✓ Branch 0 taken 487877439 times.
✓ Branch 1 taken 1313 times.
487878752 if (!getxdoor_mi(mi, dir, ind)) return false;
2638
2639 1313 mapscr* scr = screen_handles[0].base_scr;
2640 1313 int screen = scr->screen;
2641 1313 bool is_active_screen = is_in_current_region(scr);
2642
2643 925665 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2644
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 924352 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 924341 times.
924352 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2645 11 didit = true;
2646 else; //future door combo types?
2647 924352 });
2648
2649
2/4
✓ Branch 0 taken 1313 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1313 times.
✗ Branch 3 not taken.
1313 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2650 {
2651 1313 word c = scr->numFFC();
2652 1313 int screen_index_offset = get_region_screen_offset(screen);
2653
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1313 times.
1313 for (uint8_t i = 0; i < c; i++)
2654 {
2655 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2656 if (triggers && force_ex_door_trigger_any(ffc_handle, dir, ind))
2657 didit = true;
2658 else; //future door combo types?
2659 }
2660 1313 }
2661
2662 1313 return didit;
2663 487878752 }
2664
2665 15193108 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2666 {
2667 15193108 int screen = screen_handles[0].screen;
2668
2/2
✓ Branch 0 taken 387330 times.
✓ Branch 1 taken 14805778 times.
15193108 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2669 15193108 return clear_xdoors_mi(screen_handles, mi, triggers);
2670 }
2671
2672 15246211 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2673 {
2674
2/2
✓ Branch 0 taken 60984844 times.
✓ Branch 1 taken 15246211 times.
76231055 for (int dir = 0; dir < 4; ++dir)
2675
2/2
✓ Branch 0 taken 487878752 times.
✓ Branch 1 taken 60984844 times.
548863596 for (int q = 0; q < 8; ++q)
2676 548863596 remove_xdoors_mi(screen_handles, mi, dir, q, triggers);
2677 15246211 }
2678
2679 885 bool remove_lockblocks(const screen_handles_t& screen_handles)
2680 {
2681 885 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2682 }
2683
2684 139 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2685 {
2686 139 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2687 }
2688
2689 83659 bool remove_chests(const screen_handles_t& screen_handles)
2690 {
2691 83659 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2692 }
2693
2694 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2695 {
2696 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2697 }
2698
2699 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2700 {
2701 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2702 }
2703
2704 1418792 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2705 {
2706 1418792 int32_t ct=rpos_handle.ctype();
2707
2708
6/6
✓ Branch 0 taken 1418172 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1417920 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1417812 times.
✓ Branch 5 taken 108 times.
1418792 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2709 1417812 return;
2710
2711 2465 auto [cx, cy] = rpos_handle.xy();
2712
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2713 {
2714 case cL_STATUE:
2715 620 cx += 4;
2716 620 cy += 7;
2717 620 break;
2718
2719 case cR_STATUE:
2720 252 cx -= 8;
2721 252 cy -= 1;
2722 252 break;
2723
2724 case cC_STATUE:
2725 108 break;
2726 }
2727
2728
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2729 {
2730 // Finds the smallest enemy ID
2731
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 346 times.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2732 {
2733 346 guys.del(j);
2734 346 }
2735 1485 }
2736 1418792 }
2737
2738 45 static int32_t findtrigger(int32_t screen)
2739 {
2740 45 int32_t checkflag=0;
2741 45 int32_t ret = 0;
2742
2743 mapscr* screens[7];
2744
2/2
✓ Branch 0 taken 315 times.
✓ Branch 1 taken 45 times.
360 for (int32_t j = 0; j <= 6; j++)
2745 {
2746 315 screens[j] = get_scr_layer_valid(screen, j);
2747 315 }
2748
2749 45 bool sflag = false;
2750
2/2
✓ Branch 0 taken 7920 times.
✓ Branch 1 taken 45 times.
7965 for(word j=0; j<176; j++)
2751 {
2752
2/2
✓ Branch 0 taken 87648 times.
✓ Branch 1 taken 7920 times.
95568 for(int32_t layer = -1; layer < 6; ++layer)
2753 {
2754 87648 mapscr* scr = screens[layer+1];
2755
2/2
✓ Branch 0 taken 64416 times.
✓ Branch 1 taken 23232 times.
87648 if (!scr) continue;
2756
2757
2/2
✓ Branch 0 taken 32208 times.
✓ Branch 1 taken 32208 times.
64416 if(sflag)
2758 32208 checkflag = scr->sflag[j];
2759 else
2760 32208 checkflag = combobuf[scr->data[j]].flag;
2761 64416 sflag = !sflag;
2762
2/2
✓ Branch 0 taken 32208 times.
✓ Branch 1 taken 32208 times.
64416 if (sflag) --layer;
2763
2764
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 64374 times.
64416 switch(checkflag)
2765 {
2766 case mfANYFIRE:
2767 case mfSTRONGFIRE:
2768 case mfMAGICFIRE:
2769 case mfDIVINEFIRE:
2770 case mfARROW:
2771 case mfSARROW:
2772 case mfGARROW:
2773 case mfSBOMB:
2774 case mfBOMB:
2775 case mfBRANG:
2776 case mfMBRANG:
2777 case mfFBRANG:
2778 case mfWANDMAGIC:
2779 case mfREFMAGIC:
2780 case mfREFFIREBALL:
2781 case mfSWORD:
2782 case mfWSWORD:
2783 case mfMSWORD:
2784 case mfXSWORD:
2785 case mfSWORDBEAM:
2786 case mfWSWORDBEAM:
2787 case mfMSWORDBEAM:
2788 case mfXSWORDBEAM:
2789 case mfHOOKSHOT:
2790 case mfWAND:
2791 case mfHAMMER:
2792 case mfSTRIKE:
2793 42 ret += 1;
2794 42 break;
2795 }
2796 64416 }
2797 7920 }
2798
2799 45 return ret;
2800 }
2801
2802 12336 static void log_trigger_secret_reason(TriggerSource source)
2803 {
2804
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11884 times.
12336 if (source == TriggerSource::Singular)
2805 {
2806 452 Z_eventlog("Restricted Screen Secrets triggered\n");
2807 452 }
2808 else
2809 {
2810 11884 const char* source_str = "";
2811
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7296 times.
✓ Branch 3 taken 897 times.
✓ Branch 4 taken 3111 times.
✓ Branch 5 taken 500 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 75 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11884 switch (source)
2812 {
2813 case TriggerSource::Singular: break;
2814 7296 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2815 897 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2816 3111 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2817 500 case TriggerSource::Script: source_str = "a script"; break;
2818 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2819 75 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2820 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2821 case TriggerSource::SCC: source_str = "SCC"; break;
2822 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2823 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2824 }
2825 11884 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2826 }
2827 12336 }
2828
2829 // single:
2830 // >-1 : the singular triggering combo
2831 // -1: triggered by some other cause
2832 12129 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2833 {
2834 12129 log_trigger_secret_reason(source);
2835
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11677 times.
12129 if (single < 0)
2836 11677 get_screen_state(scr->screen).triggered_secrets = true;
2837
2838 12129 bool do_replay_comment = true;
2839 12129 bool from_active_screen = true;
2840 12129 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2841
2842 // Respect secret state carryovers for active screens.
2843
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11677 times.
12129 if (single >= 0) return;
2844
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 11652 times.
11677 if(scr->nocarry&mSECRET) return;
2845 11652 int cmap = scr->map;
2846 11652 int cscr = scr->screen;
2847 11652 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2848 11652 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2849
2850 11652 std::vector<int32_t> done;
2851
2/2
✓ Branch 0 taken 11447 times.
✓ Branch 1 taken 205 times.
11652 bool looped = (nmap==cmap+1 && nscr==cscr);
2852
2853
6/6
✓ Branch 0 taken 586 times.
✓ Branch 1 taken 11566 times.
✓ Branch 2 taken 86 times.
✓ Branch 3 taken 500 times.
✓ Branch 4 taken 500 times.
✓ Branch 5 taken 11652 times.
12152 while((nmap!=0) && !looped && !(nscr>=128))
2854 {
2855
7/8
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 93 times.
✓ Branch 3 taken 295 times.
✓ Branch 4 taken 93 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 89 times.
500 if (nmap - 1 == cur_map && is_in_current_region(nscr) && !get_screen_state(nscr).triggered_secrets)
2856 {
2857
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2858
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2859
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2860 4 }
2861
2862 500 cmap=nmap;
2863 500 cscr=nscr;
2864 500 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2865 500 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2866
2867
2/2
✓ Branch 0 taken 443 times.
✓ Branch 1 taken 500 times.
943 for(auto it = done.begin(); it != done.end(); it++)
2868 {
2869
2/2
✓ Branch 0 taken 357 times.
✓ Branch 1 taken 86 times.
443 if(*it == ((nmap-1)<<7)+nscr)
2870 86 looped = true;
2871 443 }
2872
2873
1/2
✓ Branch 0 taken 500 times.
✗ Branch 1 not taken.
500 done.push_back(((nmap-1)<<7)+nscr);
2874 }
2875 12129 }
2876
2877 2549 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2878 {
2879 2549 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2880 2549 }
2881
2882 19219 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2883 {
2884 19219 mapscr* scr = screen_handles[0].base_scr;
2885 19219 int screen = scr->screen;
2886
2887 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2888 // slopes in sideview mode (which required loading nearby screens in loadscr).
2889 // TODO(replays): This should just use `screen`.
2890
3/4
✓ Branch 0 taken 19219 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 18680 times.
19219 if (replay_is_active() && do_replay_comment)
2891
4/6
✓ Branch 0 taken 12133 times.
✓ Branch 1 taken 6547 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12133 times.
✓ Branch 4 taken 18680 times.
✗ Branch 5 not taken.
18680 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2892
2893
2/2
✓ Branch 0 taken 7086 times.
✓ Branch 1 taken 12133 times.
19219 if (from_active_screen)
2894 {
2895 6099291 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2896
2/4
✓ Branch 0 taken 6084496 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2662 times.
✗ Branch 3 not taken.
6407075 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
2897 319917 return trig.trigger_flags.get(TRIGFLAG_SECRETSTR);
2898 }, ctrigSECRETS);
2899 6087158 });
2900 12133 }
2901
2902 19219 int32_t ft=0; //Flag trigger?
2903 19219 int32_t msflag=0; // Misc. secret flag
2904
2905
2/2
✓ Branch 0 taken 3382544 times.
✓ Branch 1 taken 19219 times.
3401763 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2906 {
2907
4/4
✓ Branch 0 taken 79552 times.
✓ Branch 1 taken 3302992 times.
✓ Branch 2 taken 452 times.
✓ Branch 3 taken 79100 times.
3382544 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2908
2909 // Remember the misc. secret flag; if triggered, use this instead
2910
4/4
✓ Branch 0 taken 153551 times.
✓ Branch 1 taken 3149893 times.
✓ Branch 2 taken 87558 times.
✓ Branch 3 taken 65993 times.
3303444 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2911 65993 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2912
4/4
✓ Branch 0 taken 47862 times.
✓ Branch 1 taken 3189589 times.
✓ Branch 2 taken 47336 times.
✓ Branch 3 taken 526 times.
3237451 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2913 526 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2914 else
2915 3236925 msflag=0;
2916
2917
4/4
✓ Branch 0 taken 922853 times.
✓ Branch 1 taken 2380591 times.
✓ Branch 2 taken 85 times.
✓ Branch 3 taken 922768 times.
3303444 if(!high16only || single>=0)
2918 {
2919 2380676 int32_t newflag = -1;
2920
2921
2/2
✓ Branch 0 taken 4761352 times.
✓ Branch 1 taken 2380676 times.
7142028 for(int32_t iter=0; iter<2; ++iter)
2922 {
2923 4761352 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2924
2925
2/2
✓ Branch 0 taken 2380676 times.
✓ Branch 1 taken 2380676 times.
4761352 if(iter==1) checkflag=scr->sflag[i]; //Placed
2926
2927 4761352 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2928
2/2
✓ Branch 0 taken 4748883 times.
✓ Branch 1 taken 12469 times.
4761352 if (ft != -1) //Change the combos for the secret
2929 {
2930 // Use misc. secret flag instead if one is present
2931
2/2
✓ Branch 0 taken 12437 times.
✓ Branch 1 taken 32 times.
12469 if(msflag!=0)
2932 32 ft=msflag;
2933
2934 12469 rpos_handle_t rpos_handle;
2935
2/2
✓ Branch 0 taken 6540 times.
✓ Branch 1 taken 5929 times.
12469 if (from_active_screen)
2936 {
2937 5929 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2938 5929 screen_combo_modify_preroutine(rpos_handle);
2939 5929 }
2940
2941
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12469 times.
12469 if(ft==sSECNEXT)
2942 {
2943 scr->data[i]++;
2944 }
2945 else
2946 {
2947 12469 scr->data[i] = scr->secretcombo[ft];
2948 12469 scr->cset[i] = scr->secretcset[ft];
2949 }
2950 12469 newflag = scr->secretflag[ft];
2951
2952
2/2
✓ Branch 0 taken 6540 times.
✓ Branch 1 taken 5929 times.
12469 if (from_active_screen)
2953 5929 screen_combo_modify_postroutine(rpos_handle);
2954 12469 }
2955 4761352 }
2956
2957
2/2
✓ Branch 0 taken 2368213 times.
✓ Branch 1 taken 12463 times.
2380676 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2958
2959
2/2
✓ Branch 0 taken 14284056 times.
✓ Branch 1 taken 2380676 times.
16664732 for(int32_t j=1; j<=6; j++) //Layers
2960 {
2961 14284056 mapscr* layer_scr = screen_handles[j].scr;
2962
2/2
✓ Branch 0 taken 4300978 times.
✓ Branch 1 taken 9983078 times.
14284056 if (!layer_scr) continue;
2963
2964
3/4
✓ Branch 0 taken 770 times.
✓ Branch 1 taken 4300208 times.
✓ Branch 2 taken 770 times.
✗ Branch 3 not taken.
4300978 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2965
2966 4300978 int32_t newflag2 = -1;
2967
2968 // Remember the misc. secret flag; if triggered, use this instead
2969
4/4
✓ Branch 0 taken 18068 times.
✓ Branch 1 taken 4282910 times.
✓ Branch 2 taken 6284 times.
✓ Branch 3 taken 11784 times.
4300978 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
2970 11784 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
2971
4/4
✓ Branch 0 taken 132026 times.
✓ Branch 1 taken 4157168 times.
✓ Branch 2 taken 130774 times.
✓ Branch 3 taken 1252 times.
4289194 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
2972 1252 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
2973 else
2974 4287942 msflag=0;
2975
2976
2/2
✓ Branch 0 taken 8601956 times.
✓ Branch 1 taken 4300978 times.
12902934 for(int32_t iter=0; iter<2; ++iter)
2977 {
2978 8601956 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2979
2/2
✓ Branch 0 taken 4300978 times.
✓ Branch 1 taken 4300978 times.
8601956 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2980
2981 8601956 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2982
2/2
✓ Branch 0 taken 8600177 times.
✓ Branch 1 taken 1779 times.
8601956 if (ft != -1) //Change the combos for the secret
2983 {
2984 // Use misc. secret flag instead if one is present
2985
2/2
✓ Branch 0 taken 1777 times.
✓ Branch 1 taken 2 times.
1779 if(msflag!=0)
2986 2 ft=msflag;
2987
2988
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1779 times.
1779 if(ft==sSECNEXT)
2989 {
2990 layer_scr->data[i]++;
2991 }
2992 else
2993 {
2994 1779 layer_scr->data[i] = layer_scr->secretcombo[ft];
2995 1779 layer_scr->cset[i] = layer_scr->secretcset[ft];
2996 }
2997 1779 newflag2 = layer_scr->secretflag[ft];
2998 1779 int32_t c=layer_scr->data[i];
2999 1779 int32_t cs=layer_scr->cset[i];
3000
3001
3/4
✓ Branch 0 taken 908 times.
✓ Branch 1 taken 871 times.
✓ Branch 2 taken 908 times.
✗ Branch 3 not taken.
1779 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
3002 {
3003 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
3004 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
3005 }
3006 1779 }
3007 8601956 }
3008
3009
2/2
✓ Branch 0 taken 1766 times.
✓ Branch 1 taken 4299212 times.
4300978 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
3010 4300978 }
3011 2380676 }
3012 3303444 }
3013
3014 19219 word c = scr->numFFC();
3015
2/2
✓ Branch 0 taken 508206 times.
✓ Branch 1 taken 19219 times.
527425 for(word i=0; i<c; i++) //FFC 'trigger flags'
3016 {
3017
3/4
✓ Branch 0 taken 494152 times.
✓ Branch 1 taken 14054 times.
✓ Branch 2 taken 14054 times.
✗ Branch 3 not taken.
508206 if(single>=0) if(i+176!=single) continue;
3018
3019
3/4
✓ Branch 0 taken 166649 times.
✓ Branch 1 taken 327503 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166649 times.
494152 if((!high16only)||(single>=0))
3020 {
3021 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
3022 {
3023 327503 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3024 //No placed flags yet
3025
3026 327503 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
3027
2/2
✓ Branch 0 taken 327472 times.
✓ Branch 1 taken 31 times.
327503 if (ft != -1) //Change the ffc's combo
3028 {
3029
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
3030 {
3031 zc_ffc_modify(scr->ffcs[i], 1);
3032 }
3033 else
3034 {
3035 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
3036 31 scr->ffcs[i].cset = scr->secretcset[ft];
3037 }
3038 31 }
3039 }
3040 327503 }
3041 494152 }
3042
3043
2/2
✓ Branch 0 taken 16722 times.
✓ Branch 1 taken 2497 times.
19219 if(checktrigger) //Hit all triggers->16-31
3044 {
3045 2497 checktrigger=false;
3046
3047
2/2
✓ Branch 0 taken 2473 times.
✓ Branch 1 taken 24 times.
2497 if(scr->flags6&fTRIGGERF1631)
3048 {
3049 24 int32_t tr = findtrigger(screen); //Normal flags
3050
3051
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 10 times.
24 if(tr)
3052 {
3053 14 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
3054 14 goto endhe;
3055 }
3056 10 }
3057 2483 }
3058
3059
2/2
✓ Branch 0 taken 3380080 times.
✓ Branch 1 taken 19205 times.
3399285 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
3060 {
3061 //If it's an enemies->secret screen, only do the high 16 if told to
3062 //That way you can have secret and burn/bomb entrance separately
3063 3380080 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
3064
6/6
✓ Branch 0 taken 2779920 times.
✓ Branch 1 taken 600160 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3294896 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3380080 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
3065 {
3066 3314432 int32_t newflag = -1;
3067
3068
2/2
✓ Branch 0 taken 6628864 times.
✓ Branch 1 taken 3314432 times.
9943296 for(int32_t iter=0; iter<2; ++iter)
3069 {
3070 6628864 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
3071
3072
2/2
✓ Branch 0 taken 3314432 times.
✓ Branch 1 taken 3314432 times.
6628864 if(iter==1) checkflag=scr->sflag[i]; //Placed
3073
3074
4/4
✓ Branch 0 taken 200805 times.
✓ Branch 1 taken 6428059 times.
✓ Branch 2 taken 133230 times.
✓ Branch 3 taken 67575 times.
6628864 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3075 {
3076 67575 rpos_handle_t rpos_handle;
3077
2/2
✓ Branch 0 taken 10367 times.
✓ Branch 1 taken 57208 times.
67575 if (from_active_screen)
3078 {
3079 57208 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
3080 57208 screen_combo_modify_preroutine(rpos_handle);
3081 57208 }
3082
3083 67575 scr->data[i] = scr->secretcombo[checkflag-16+4];
3084 67575 scr->cset[i] = scr->secretcset[checkflag-16+4];
3085 67575 newflag = scr->secretflag[checkflag-16+4];
3086
3087
2/2
✓ Branch 0 taken 10367 times.
✓ Branch 1 taken 57208 times.
67575 if (from_active_screen)
3088 57208 screen_combo_modify_postroutine(rpos_handle);
3089 67575 }
3090 6628864 }
3091
3092
2/2
✓ Branch 0 taken 3246885 times.
✓ Branch 1 taken 67547 times.
3314432 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
3093
3094
2/2
✓ Branch 0 taken 19886592 times.
✓ Branch 1 taken 3314432 times.
23201024 for(int32_t j=1; j<=6; j++) //Layers
3095 {
3096 19886592 mapscr* layer_scr = screen_handles[j].scr;
3097
2/2
✓ Branch 0 taken 5992096 times.
✓ Branch 1 taken 13894496 times.
19886592 if (!layer_scr) continue;
3098
3099 5992096 int32_t newflag2 = -1;
3100
3101
2/2
✓ Branch 0 taken 11984192 times.
✓ Branch 1 taken 5992096 times.
17976288 for(int32_t iter=0; iter<2; ++iter)
3102 {
3103 11984192 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
3104
3105
2/2
✓ Branch 0 taken 5992096 times.
✓ Branch 1 taken 5992096 times.
11984192 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
3106
3107
4/4
✓ Branch 0 taken 159433 times.
✓ Branch 1 taken 11824759 times.
✓ Branch 2 taken 136546 times.
✓ Branch 3 taken 22887 times.
11984192 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3108 {
3109 22887 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
3110 22887 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
3111 22887 newflag2 = layer_scr->secretflag[checkflag-16+4];
3112 22887 }
3113 11984192 }
3114
3115
2/2
✓ Branch 0 taken 5969209 times.
✓ Branch 1 taken 22887 times.
5992096 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
3116 5992096 }
3117 3314432 }
3118 3380080 }
3119
3120
2/2
✓ Branch 0 taken 507946 times.
✓ Branch 1 taken 19205 times.
527151 for(word i=0; i<c; i++) // FFCs
3121 {
3122
6/6
✓ Branch 0 taken 467925 times.
✓ Branch 1 taken 40021 times.
✓ Branch 2 taken 15497 times.
✓ Branch 3 taken 492449 times.
✓ Branch 4 taken 3657 times.
✓ Branch 5 taken 11840 times.
507946 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
3123 {
3124 496106 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3125
3126 //No placed flags yet
3127
4/4
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 496013 times.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 12 times.
496106 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
3128 {
3129
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
3130 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
3131 else
3132 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
3133 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
3134 12 }
3135 496106 }
3136 527151 }
3137
3138 endhe:
3139
3140
1/2
✓ Branch 0 taken 19219 times.
✗ Branch 1 not taken.
19219 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
3141 {
3142 if (from_active_screen)
3143 activated_timed_warp = true;
3144 scr->timedwarptics = 0;
3145 }
3146 19219 }
3147
3148 // x,y are world coordinates.
3149 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3150 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3151 13969610 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3152 {
3153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13969610 times.
13969610 if (!is_in_world_bounds(x, y)) return false;
3154
3155 13969610 bool found_cflag = false;
3156 13969610 bool found_nflag = false;
3157 13969610 bool single16 = false;
3158 13969610 rpos_t rpos = rpos_t::None;
3159
3160
2/2
✓ Branch 0 taken 13967509 times.
✓ Branch 1 taken 97774994 times.
111742503 for (int32_t layer = -1; layer < 6; layer++)
3161 {
3162
2/2
✓ Branch 0 taken 97772893 times.
✓ Branch 1 taken 2101 times.
97774994 if (MAPFLAG2(layer, x, y) == flag)
3163 {
3164 2101 found_nflag = true;
3165 2101 break;
3166 }
3167 97772893 }
3168
3169
2/2
✓ Branch 0 taken 13969221 times.
✓ Branch 1 taken 97785575 times.
111754796 for (int32_t layer = -1; layer < 6; layer++)
3170 {
3171
2/2
✓ Branch 0 taken 97785186 times.
✓ Branch 1 taken 389 times.
97785575 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3172 {
3173 389 found_cflag = true;
3174 389 break;
3175 }
3176 97785186 }
3177
3178
2/2
✓ Branch 0 taken 97787270 times.
✓ Branch 1 taken 13969610 times.
111756880 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3179 {
3180
2/2
✓ Branch 0 taken 97772563 times.
✓ Branch 1 taken 14707 times.
97787270 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3181 {
3182
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14595 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14707 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3183 {
3184 112 rpos = COMBOPOS_REGION(x, y);
3185 112 }
3186
3/4
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 14539 times.
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
14595 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3187 {
3188 56 rpos = COMBOPOS_REGION(x, y);
3189 56 single16 = true;
3190 56 }
3191 14707 }
3192
3193
2/2
✓ Branch 0 taken 97784547 times.
✓ Branch 1 taken 2723 times.
97787270 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3194 {
3195
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 2468 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2723 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3196 {
3197 255 rpos = COMBOPOS_REGION(x, y);
3198 255 }
3199
3/4
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 2439 times.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
2468 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3200 {
3201 29 rpos = COMBOPOS_REGION(x, y);
3202 29 single16 = true;
3203 29 }
3204 2723 }
3205 97787270 }
3206
3207 13969610 out_rpos = rpos;
3208 13969610 out_single16 = single16;
3209
4/4
✓ Branch 0 taken 13967509 times.
✓ Branch 1 taken 2101 times.
✓ Branch 2 taken 13967124 times.
✓ Branch 3 taken 385 times.
13969610 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3210 13969610 }
3211
3212 4600000 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3213 {
3214
8/8
✓ Branch 0 taken 4599760 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4597863 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4597343 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4596391 times.
4600000 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3215
3216 4596391 mapscr* scr = NULL;
3217 4596391 int32_t screen = -1;
3218 4596391 rpos_t trigger_rpos = rpos_t::None;
3219 4596391 bool single16 = false;
3220
3221 4596391 std::vector<std::pair<int, int>> coords;
3222
1/2
✓ Branch 0 taken 4596391 times.
✗ Branch 1 not taken.
4596391 coords.push_back({x, y});
3223
1/2
✓ Branch 0 taken 4596391 times.
✗ Branch 1 not taken.
4596391 coords.push_back({x + 15, y});
3224
1/2
✓ Branch 0 taken 4596391 times.
✗ Branch 1 not taken.
4596391 coords.push_back({x, y + 15});
3225
1/2
✓ Branch 0 taken 4596391 times.
✗ Branch 1 not taken.
4596391 coords.push_back({x + 15, y + 15});
3226 4596391 std::vector<rpos_t> rposes_seen;
3227
2/2
✓ Branch 0 taken 4593894 times.
✓ Branch 1 taken 18380045 times.
87251441 for (auto [x, y] : coords)
3228 {
3229
2/4
✓ Branch 0 taken 18380045 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18380045 times.
✗ Branch 3 not taken.
36760090 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3230
2/2
✓ Branch 0 taken 18166644 times.
✓ Branch 1 taken 213401 times.
18380045 if (rpos == rpos_t::None)
3231 213401 continue;
3232
3233
4/6
✓ Branch 0 taken 18166644 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18166644 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 18166633 times.
36333288 if (MAPFFCOMBOFLAG(x, y) == flag)
3234 {
3235
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3236 11 break;
3237 }
3238
3239 18166633 bool seen = false;
3240
2/2
✓ Branch 0 taken 13969610 times.
✓ Branch 1 taken 22872423 times.
36842033 for (rpos_t r : rposes_seen)
3241 {
3242
2/2
✓ Branch 0 taken 18675400 times.
✓ Branch 1 taken 4197023 times.
22872423 if (r == rpos)
3243 {
3244 4197023 seen = true;
3245 4197023 break;
3246 }
3247 }
3248
2/2
✓ Branch 0 taken 13969610 times.
✓ Branch 1 taken 4197023 times.
18166633 if (seen)
3249 4197023 continue;
3250
3251
1/2
✓ Branch 0 taken 13969610 times.
✗ Branch 1 not taken.
13969610 rposes_seen.push_back(rpos);
3252
4/6
✓ Branch 0 taken 13969610 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13969610 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2486 times.
✓ Branch 5 taken 13967124 times.
27939220 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3253 {
3254
2/4
✓ Branch 0 taken 2486 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2486 times.
✗ Branch 3 not taken.
4972 screen = get_screen_for_world_xy(x, y);
3255 2486 break;
3256 }
3257 }
3258
3259
3/4
✓ Branch 0 taken 2497 times.
✓ Branch 1 taken 4593894 times.
✓ Branch 2 taken 2497 times.
✗ Branch 3 not taken.
4596391 if (screen != -1) scr = get_scr(screen);
3260
2/2
✓ Branch 0 taken 2497 times.
✓ Branch 1 taken 4593894 times.
4596391 if (!scr) return false;
3261
3262
2/2
✓ Branch 0 taken 2045 times.
✓ Branch 1 taken 452 times.
2497 if (trigger_rpos == rpos_t::None)
3263 {
3264 2045 checktrigger = true;
3265
1/2
✓ Branch 0 taken 2045 times.
✗ Branch 1 not taken.
2045 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3266 2045 }
3267 else
3268 {
3269 452 checktrigger = true;
3270
2/4
✓ Branch 0 taken 452 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 452 times.
✗ Branch 3 not taken.
452 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3271 }
3272
3273
1/2
✓ Branch 0 taken 2497 times.
✗ Branch 1 not taken.
2497 sfx(scr->secretsfx);
3274
3275
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 2476 times.
2497 if(scr->flags6&fTRIGGERFPERM)
3276 {
3277
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 int32_t flags_remaining = findtrigger(screen); //Normal flags
3278
3279
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 9 times.
21 if (flags_remaining)
3280 {
3281
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3282 12 setflag=false;
3283 12 }
3284
3285 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3286 // which case only the screen state for mSECRET may be set below.
3287
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 3 times.
21 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3288 {
3289
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3290 6 }
3291 21 }
3292
3293
5/6
✓ Branch 0 taken 2383 times.
✓ Branch 1 taken 114 times.
✓ Branch 2 taken 2383 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1108 times.
✓ Branch 5 taken 1275 times.
2497 if (setflag && canPermSecret(cur_dmap, screen))
3294
2/2
✓ Branch 0 taken 812 times.
✓ Branch 1 taken 463 times.
2087 if(!(scr->flags5&fTEMPSECRETS))
3295
1/2
✓ Branch 0 taken 812 times.
✗ Branch 1 not taken.
812 setmapflag(scr, mSECRET);
3296
3297 2497 return true;
3298 4600000 }
3299
3300 15372897 void update_slopes()
3301 {
3302
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 15372897 times.
15515253 for (auto& p : slopes)
3303 {
3304 142356 slope_object& s = p.second;
3305 142356 s.updateslope(); //sets old x/y poses
3306 }
3307 15372897 }
3308
3309 14913123 void update_freeform_combos()
3310 {
3311 14913123 ffscript_engine(false);
3312
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14888951 times.
14913123 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3313 {
3314 14888951 int wrap_right = world_w + 32;
3315 14888951 int wrap_bottom = world_h + 32;
3316
3317 487926963 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3318 473038012 mapscr* scr = ffc_handle.scr;
3319 473038012 ffcdata& thisffc = *ffc_handle.ffc;
3320
3321 // Combo 0?
3322
2/2
✓ Branch 0 taken 47283515 times.
✓ Branch 1 taken 425754497 times.
473038012 if(thisffc.data==0)
3323 425754497 return;
3324
3325 // Changer?
3326
2/2
✓ Branch 0 taken 562821 times.
✓ Branch 1 taken 46720694 times.
47283515 if(thisffc.flags&ffc_changer)
3327 562821 return;
3328
3329 // Stationary?
3330
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 46710850 times.
46720694 if(thisffc.flags&ffc_stationary)
3331 9844 return;
3332
3333 // Frozen because Hero's holding up an item?
3334
3/4
✓ Branch 0 taken 157429 times.
✓ Branch 1 taken 46553421 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 157429 times.
46710850 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3335 157429 return;
3336
3337 // Check for changers
3338
2/2
✓ Branch 0 taken 31045342 times.
✓ Branch 1 taken 15508079 times.
46553421 if (thisffc.link==0)
3339 {
3340 446641935 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3341
2/2
✓ Branch 0 taken 15506442 times.
✓ Branch 1 taken 415627414 times.
431133856 if (ffc_handle.id == other_ffc_handle.id)
3342 15506442 return true;
3343
3344 415627414 ffcdata& otherffc = *other_ffc_handle.ffc;
3345 // Combo 0?
3346
2/2
✓ Branch 0 taken 147056060 times.
✓ Branch 1 taken 268571354 times.
415627414 if(otherffc.data==0)
3347 268571354 return true;
3348
3349 // Not a changer?
3350
2/2
✓ Branch 0 taken 142874031 times.
✓ Branch 1 taken 4182029 times.
147056060 if(!(otherffc.flags&ffc_changer))
3351 142874031 return true;
3352
3353 // Ignore this changer?
3354
4/4
✓ Branch 0 taken 564215 times.
✓ Branch 1 taken 3617814 times.
✓ Branch 2 taken 308097 times.
✓ Branch 3 taken 3309717 times.
4182029 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3355 872312 return true;
3356
3357
3/4
✓ Branch 0 taken 2870799 times.
✓ Branch 1 taken 438918 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3663 times.
3313380 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3358 ( // At exactly the same position,
3359
2/2
✓ Branch 0 taken 217547 times.
✓ Branch 1 taken 2653252 times.
2870799 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3360
2/2
✓ Branch 0 taken 2435705 times.
✓ Branch 1 taken 2653252 times.
217547 ||
3361 //or imprecision and close enough
3362
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5306504 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3363 )
3364 && //and...
3365
2/2
✓ Branch 0 taken 3663 times.
✓ Branch 1 taken 2870960 times.
2874623 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3366 {
3367 3663 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3368 3663 return false;
3369 }
3370
3371 2870960 return true;
3372 430082568 });
3373 15508079 }
3374
3375
2/2
✓ Branch 0 taken 31045342 times.
✓ Branch 1 taken 15508079 times.
46553421 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3376
4/4
✓ Branch 0 taken 15508079 times.
✓ Branch 1 taken 31045342 times.
✓ Branch 2 taken 15430786 times.
✓ Branch 3 taken 15614556 times.
46553421 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3377 {
3378
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 15431947 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
15614556 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3379 {
3380 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3381 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3382 97278 thisffc.x += linked_ffc->vx;
3383 97278 thisffc.y += linked_ffc->vy;
3384 97278 }
3385 else
3386 {
3387 15517278 thisffc.prev_changer_x = thisffc.x.getZLong();
3388 15517278 thisffc.prev_changer_y = thisffc.y.getZLong();
3389 15517278 thisffc.x += thisffc.vx;
3390 15517278 thisffc.y += thisffc.vy;
3391 15517278 thisffc.vx += thisffc.ax;
3392 15517278 thisffc.vy += thisffc.ay;
3393
3394
3395
2/2
✓ Branch 0 taken 1192093 times.
✓ Branch 1 taken 14325185 times.
15517278 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3396 {
3397
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vx>128) thisffc.vx=128;
3398
3399
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vx<-128) thisffc.vx=-128;
3400
3401
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vy>128) thisffc.vy=128;
3402
3403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vy<-128) thisffc.vy=-128;
3404 14325185 }
3405 }
3406 15614556 }
3407 else
3408 {
3409
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76132 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
30938865 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3410 76132 thisffc.delay--;
3411 }
3412
3413 // Check if the FFC's off the side of the screen
3414
3415 // Left
3416
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 15681400 times.
15691849 if(thisffc.x<-32)
3417 {
3418
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3419 {
3420 253 thisffc.x = wrap_right+(thisffc.x+32);
3421 253 thisffc.solid_update(false);
3422 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3423 // Re-enable previous changer
3424 253 thisffc.changer_x = -1000;
3425 253 thisffc.changer_y = -1000;
3426 253 }
3427
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3428 {
3429 69 zc_ffc_set(thisffc, 0);
3430 69 thisffc.flags&=~ffc_carryover;
3431 69 }
3432 10449 }
3433 // Right
3434
2/2
✓ Branch 0 taken 15681219 times.
✓ Branch 1 taken 181 times.
15681400 else if(thisffc.x>=wrap_right)
3435 {
3436
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3437 {
3438 128 thisffc.x = thisffc.x-wrap_right-32;
3439 128 thisffc.solid_update(false);
3440 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3441 128 thisffc.changer_x = -1000;
3442 128 thisffc.changer_y = -1000;
3443 128 }
3444 else
3445 {
3446 53 zc_ffc_set(thisffc, 0);
3447 53 thisffc.flags&=~ffc_carryover;
3448 }
3449 181 }
3450
3451 // Top
3452
2/2
✓ Branch 0 taken 25806 times.
✓ Branch 1 taken 15666043 times.
15691849 if(thisffc.y<-32)
3453 {
3454
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25798 times.
25806 if(scr->flags6&fWRAPAROUNDFF)
3455 {
3456 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3457 8 thisffc.solid_update(false);
3458 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3459 8 thisffc.changer_x = -1000;
3460 8 thisffc.changer_y = -1000;
3461 8 }
3462
2/2
✓ Branch 0 taken 25481 times.
✓ Branch 1 taken 317 times.
25798 else if(thisffc.y<-64)
3463 {
3464 317 zc_ffc_set(thisffc, 0);
3465 317 thisffc.flags&=~ffc_carryover;
3466 317 }
3467 25806 }
3468 // Bottom
3469
2/2
✓ Branch 0 taken 15665175 times.
✓ Branch 1 taken 868 times.
15666043 else if(thisffc.y>=wrap_bottom)
3470 {
3471
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 115 times.
868 if(scr->flags6&fWRAPAROUNDFF)
3472 {
3473 753 thisffc.y = thisffc.y-wrap_bottom-32;
3474 753 thisffc.solid_update(false);
3475 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3476 753 thisffc.changer_x = -1000;
3477 753 thisffc.changer_y = -1000;
3478 753 }
3479 else
3480 {
3481 115 zc_ffc_set(thisffc, 0);
3482 115 thisffc.flags&=~ffc_carryover;
3483 }
3484 868 }
3485 15691849 thisffc.solid_update();
3486 442176440 });
3487 14888951 }
3488 14913123 }
3489
3490 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3491 {
3492 for(int q = 0; q < 7; ++q)
3493 {
3494 if(layers&(1<<q)) //if layer is to be checked
3495 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3496 return true;
3497 }
3498 return false;
3499 }
3500
3501 229 optional<int> nextscr(int screen, int dir)
3502 {
3503 229 auto [m, s] = nextscr2(cur_map, screen, dir);
3504
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 229 times.
229 if (m == -1) return nullopt;
3505 458 return (m<<7) + s;
3506 229 }
3507
3508 1064 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3509 {
3510 1064 int32_t map = cur_map;
3511
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1064 times.
1064 int32_t screen = screenscrolling ? scrolling_hero_screen : Hero.current_screen;
3512 1064 return nextscr2(map, screen, dir);
3513 }
3514
3515 5580 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3516 {
3517 5580 screen = screen_index_direction(screen, (direction)dir);
3518
3519 // need to check for screens on other maps, 's' not valid, etc.
3520 5580 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3521
3522 // Fun fact: when a scrolling warp is triggered, this function
3523 // is never even called! - Saf
3524
2/2
✓ Branch 0 taken 3328 times.
✓ Branch 1 taken 2252 times.
6124 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3525 {
3526
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 527 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 697 times.
2252 switch(dir)
3527 {
3528 case up:
3529
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3530
3531 83 break;
3532
3533 case down:
3534
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 448 times.
527 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3535
3536 79 break;
3537
3538 case left:
3539
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 337 times.
546 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3540
3541 209 break;
3542
3543 case right:
3544
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 524 times.
697 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3545
3546 173 break;
3547 }
3548
3549 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3550 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3551 544 }
3552
3553 nowarp:
3554
4/4
✓ Branch 0 taken 5516 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5404 times.
5580 if(screen<0||screen>=128)
3555 176 return {-1, -1};
3556
3557 5404 return {map, screen};
3558 5580 }
3559
3560 403 optional<int> nextscr_mi(int mi, int dir)
3561 {
3562 403 int map = mi/MAPSCRSNORMAL;
3563 403 int screen = mi%MAPSCRSNORMAL;
3564 403 auto [m, s] = nextscr2(map, screen, dir);
3565
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 402 times.
403 if (m == -1) return nullopt;
3566 804 return (m<<7) + s;
3567 403 }
3568
3569 2295 void bombdoor(int32_t x,int32_t y)
3570 {
3571
2/2
✓ Branch 0 taken 2274 times.
✓ Branch 1 taken 21 times.
2295 if (!is_in_world_bounds(x, y))
3572 21 return;
3573
3574 2274 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3575 2274 mapscr* scr = rpos_handle.scr;
3576 2274 int screen = scr->screen;
3577 3078 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3578 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3579
3580
12/12
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2196 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 68 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 68 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 68 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 68 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 68 times.
2274 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3581 {
3582 68 scr->door[0]=dBOMBED;
3583 68 putdoor(scr, scrollbuf, 0, dBOMBED);
3584 68 setmapflag(scr, mDOOR_UP);
3585 68 markBmap(-1, screen);
3586
3587
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 if(auto v = nextscr(screen, up))
3588 {
3589 68 setmapflag_mi(*v, mDOOR_DOWN);
3590 68 markBmap(-1,*v-(get_currdmap()<<7));
3591 68 }
3592 68 }
3593
3594
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2225 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2274 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3595 {
3596 39 scr->door[1]=dBOMBED;
3597 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3598 39 setmapflag(scr, mDOOR_DOWN);
3599 39 markBmap(-1, rpos_handle.screen);
3600
3601
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3602 {
3603 39 setmapflag_mi(*v, mDOOR_UP);
3604 39 markBmap(-1,*v-(get_currdmap()<<7));
3605 39 }
3606 39 }
3607
3608
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2207 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2274 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3609 {
3610 51 scr->door[2]=dBOMBED;
3611 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3612 51 setmapflag(scr, mDOOR_LEFT);
3613 51 markBmap(-1, rpos_handle.screen);
3614
3615
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3616 {
3617 51 setmapflag_mi(*v, mDOOR_RIGHT);
3618 51 markBmap(-1,*v-(get_currdmap()<<7));
3619 51 }
3620 51 }
3621
3622
12/12
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 2189 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 71 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 71 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 71 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 71 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 71 times.
2274 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3623 {
3624 71 scr->door[3]=dBOMBED;
3625 71 putdoor(scr, scrollbuf, 3, dBOMBED);
3626 71 setmapflag(scr, mDOOR_RIGHT);
3627 71 markBmap(-1, rpos_handle.screen);
3628
3629
1/2
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
71 if(auto v = nextscr(rpos_handle.screen, right))
3630 {
3631 71 setmapflag_mi(*v, mDOOR_LEFT);
3632 71 markBmap(-1,*v-(get_currdmap()<<7));
3633 71 }
3634 71 }
3635 2295 }
3636
3637 7116360590 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3638 bool over, bool transp)
3639 {
3640 7116360590 auto& cmb = combobuf[cid];
3641
2/2
✓ Branch 0 taken 93673 times.
✓ Branch 1 taken 7116266917 times.
7116360590 if(cmb.animflags & AF_EDITOR_ONLY)
3642 93673 return;
3643
2/2
✓ Branch 0 taken 3924728355 times.
✓ Branch 1 taken 3191538562 times.
7116266917 if(over)
3644 {
3645
2/2
✓ Branch 0 taken 841117 times.
✓ Branch 1 taken 3923887238 times.
3924728355 if(cmb.animflags & AF_TRANSPARENT)
3646 841117 transp = !transp;
3647
2/2
✓ Branch 0 taken 328633561 times.
✓ Branch 1 taken 3596094794 times.
3924728355 if(transp)
3648 328633561 overcombotranslucent(dest, x, y, cid, cset, 128);
3649 3596094794 else overcombo(dest, x, y, cid, cset);
3650 3924728355 }
3651 3191538562 else putcombo(dest, x, y, cid, cset);
3652 7116360590 }
3653 7116369038 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3654 int32_t cset, byte layer, bool over, bool transp)
3655 {
3656
2/2
✓ Branch 0 taken 846974041 times.
✓ Branch 1 taken 6269394997 times.
7116369038 if (rpos != rpos_t::None)
3657 {
3658 6269394997 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3659
2/2
✓ Branch 0 taken 748468 times.
✓ Branch 1 taken 6268646529 times.
6269394997 if (plrpos != rpos_t::None)
3660 {
3661 6268646529 bool dosw = false;
3662
4/4
✓ Branch 0 taken 67998 times.
✓ Branch 1 taken 6268578531 times.
✓ Branch 2 taken 59550 times.
✓ Branch 3 taken 8448 times.
6268646529 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3663 {
3664
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3665 {
3666 draw_cmb(dest, x, y,
3667 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3668 }
3669 8448 dosw = true;
3670 8448 }
3671
4/4
✓ Branch 0 taken 35584100 times.
✓ Branch 1 taken 6233053981 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 35575652 times.
6268638081 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3672 {
3673 8448 dosw = true;
3674 8448 }
3675
2/2
✓ Branch 0 taken 6268629633 times.
✓ Branch 1 taken 16896 times.
6268646529 if (dosw)
3676 {
3677
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3678 {
3679 default: case swPOOF:
3680 break; //Nothing special here
3681 case swFLICKER:
3682 {
3683
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3684 8448 break; //Drawn this frame
3685 8448 return; //Not drawn this frame
3686 }
3687 case swRISE:
3688 {
3689 //Draw rising up
3690 y -= 8-(abs(Hero.switchhookclk-32)/4);
3691 break;
3692 }
3693 }
3694 8448 }
3695 6268638081 }
3696 6269386549 }
3697
3698 7116360590 draw_cmb(dest, x, y, cid, cset, over, transp);
3699 7116369038 }
3700
3701 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3702 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3703 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3704 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3705 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3706 //
3707 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3708 //
3709 // -16 < comboPositionX*16 + x < bitmapWidth
3710 // -16 < comboPositionY*16 + y < bitmapHeight
3711 //
3712 // The following start/end values are derived directly from the above.
3713 //
3714 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3715 44013493 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3716 {
3717 // if (bmp->clip)
3718 // {
3719 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3720 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3721 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3722 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3723 // return;
3724 // }
3725
3726
2/2
✓ Branch 0 taken 2403805 times.
✓ Branch 1 taken 41609688 times.
44013493 start_x = MAX(0, ceil((-15 - x) / 16.0));
3727
2/2
✓ Branch 0 taken 2411779 times.
✓ Branch 1 taken 41601714 times.
44013493 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3728
2/2
✓ Branch 0 taken 42475523 times.
✓ Branch 1 taken 1537970 times.
44013493 start_y = MAX(0, ceil((-15 - y) / 16.0));
3729
2/2
✓ Branch 0 taken 1873754 times.
✓ Branch 1 taken 42139739 times.
44013493 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3730 44013493 }
3731
3732 195518234 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3733 {
3734
1/2
✓ Branch 0 taken 195518234 times.
✗ Branch 1 not taken.
195518234 if(!show_ffcs) return;
3735 195518234 mapscr* base_scr = screen_handle.base_scr;
3736
3737 195518234 y += playing_field_offset;
3738
3739 195518234 bool is_overhead = layer == -1000;
3740
2/2
✓ Branch 0 taken 53194574 times.
✓ Branch 1 taken 142323660 times.
195518234 bool is_bg_layer = layer < 0 && !is_overhead;
3741
2/2
✓ Branch 0 taken 35498386 times.
✓ Branch 1 taken 160019848 times.
195518234 int real_layer = is_bg_layer ? abs(layer) : layer;
3742
2/2
✓ Branch 0 taken 195518234 times.
✓ Branch 1 taken 5603609062 times.
5799127296 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3743 {
3744
2/2
✓ Branch 0 taken 217455144 times.
✓ Branch 1 taken 5386153918 times.
5603609062 if (base_scr->ffcs[i].data == 0)
3745 5386153918 continue;
3746
3/4
✓ Branch 0 taken 39536116 times.
✓ Branch 1 taken 177919028 times.
✓ Branch 2 taken 39536116 times.
✗ Branch 3 not taken.
217455144 if (is_bg_layer && base_scr->ffcs[i].layer == layer)
3747 ; // ffc is set negative, skip bg layer flag checks
3748 else
3749 {
3750
4/4
✓ Branch 0 taken 39536089 times.
✓ Branch 1 taken 177919055 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 19768031 times.
217455144 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3751 19768031 continue;
3752
4/4
✓ Branch 0 taken 39535883 times.
✓ Branch 1 taken 158151230 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 19767825 times.
197687113 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3753 19767825 continue;
3754
4/4
✓ Branch 0 taken 158156192 times.
✓ Branch 1 taken 19763096 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 138388134 times.
177919288 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3755 138388134 continue;
3756 }
3757
3758
6/6
✓ Branch 0 taken 3311080 times.
✓ Branch 1 taken 36220074 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3305970 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
39531154 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3759 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3760
3761 39528670 base_scr->ffcs[i].draw_ffc(bmp, x, y, is_overhead);
3762 39528670 }
3763 195518234 }
3764 177326702 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3765 {
3766
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 177326702 times.
177326702 if(!show_ffcs) return;
3767 359578346 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3768 182251644 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3769 182251644 do_ffc_layer(bmp, layer, handle, 0, 0);
3770 182251644 });
3771 177326702 }
3772 110519582 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3773 {
3774 110519582 mapscr* scr = screen_handle.scr;
3775 110519582 mapscr* base_scr = screen_handle.base_scr;
3776
3777
4/4
✓ Branch 0 taken 69289652 times.
✓ Branch 1 taken 41229930 times.
✓ Branch 2 taken 41229930 times.
✓ Branch 3 taken 110519582 times.
110519582 if (type == -3 || type == -4)
3778 {
3779 82459860 y += playing_field_offset;
3780
3781
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
82459860 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3782 {
3783 if (base_scr->ffcs[i].data == 0)
3784 continue;
3785
3786 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3787 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3788
3789 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3790 }
3791 return;
3792 }
3793
3794 110519582 x -= viewport.x;
3795 110519582 y -= viewport.y - playing_field_offset;
3796
3797 110519582 bool over = true, transp = false;
3798 110519582 int layer = screen_handle.layer;
3799
3800
7/8
✓ Branch 0 taken 86251324 times.
✓ Branch 1 taken 24268258 times.
✓ Branch 2 taken 15026723 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 62953031 times.
✓ Branch 5 taken 23298293 times.
✓ Branch 6 taken 3907648 times.
✓ Branch 7 taken 5333887 times.
110519582 switch(type ? type : layer)
3801 {
3802 case -2: //push blocks
3803
2/2
✓ Branch 0 taken 21723101 times.
✓ Branch 1 taken 41229930 times.
62953031 if (scr)
3804 {
3805
2/2
✓ Branch 0 taken 3823265776 times.
✓ Branch 1 taken 62296123 times.
3859280087 for(int32_t i=0; i<176; i++)
3806 {
3807 3823265776 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3808
3809
10/10
✓ Branch 0 taken 3823096811 times.
✓ Branch 1 taken 168965 times.
✓ Branch 2 taken 3821619606 times.
✓ Branch 3 taken 1477205 times.
✓ Branch 4 taken 3820986367 times.
✓ Branch 5 taken 633239 times.
✓ Branch 6 taken 53394531 times.
✓ Branch 7 taken 3767591836 times.
✓ Branch 8 taken 100280201 times.
✓ Branch 9 taken 57139160 times.
3866857289 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3810
6/8
✓ Branch 0 taken 3818103718 times.
✓ Branch 1 taken 50511882 times.
✓ Branch 2 taken 3818103718 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3818103718 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 43591513 times.
✓ Branch 7 taken 3774512205 times.
3820986367 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3811 {
3812
4/4
✓ Branch 0 taken 5123619 times.
✓ Branch 1 taken 782002 times.
✓ Branch 2 taken 3849 times.
✓ Branch 3 taken 5119770 times.
206466023 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3813 5905621 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3814 5905621 }
3815 3837556986 }
3816 62296123 }
3817 103526053 return;
3818
3819 case -1: //over combo
3820
1/2
✓ Branch 0 taken 23298293 times.
✗ Branch 1 not taken.
23298293 if (scr)
3821 {
3822
2/2
✓ Branch 0 taken 4100499568 times.
✓ Branch 1 taken 23298293 times.
4123797861 for(int32_t i=0; i<176; i++)
3823 {
3824
2/2
✓ Branch 0 taken 4081169648 times.
✓ Branch 1 taken 19329920 times.
4100499568 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3825 {
3826
4/4
✓ Branch 0 taken 15574819 times.
✓ Branch 1 taken 3755101 times.
✓ Branch 2 taken 22336 times.
✓ Branch 3 taken 15552483 times.
19329920 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3827 19329920 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3828 19329920 }
3829 4100499568 }
3830 23298293 }
3831 23298293 return;
3832
3833 case 1:
3834 case 4:
3835 case 5:
3836 case 6:
3837
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15026723 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15026723 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3838 {
3839
1/2
✓ Branch 0 taken 15026723 times.
✗ Branch 1 not taken.
15026723 if (scr)
3840 {
3841
2/2
✓ Branch 0 taken 13331916 times.
✓ Branch 1 taken 1694807 times.
15026723 if(base_scr->layeropacity[layer-1]!=255)
3842 1694807 transp = true;
3843 15026723 break;
3844 }
3845 }
3846 return;
3847
3848 case 2:
3849
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3907648 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3907648 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3850 {
3851
1/2
✓ Branch 0 taken 3907648 times.
✗ Branch 1 not taken.
3907648 if (scr)
3852 {
3853
2/2
✓ Branch 0 taken 3671362 times.
✓ Branch 1 taken 236286 times.
3907648 if(base_scr->layeropacity[layer-1]!=255)
3854 236286 transp = true;
3855
3856
2/2
✓ Branch 0 taken 3760193 times.
✓ Branch 1 taken 147455 times.
3907648 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3857 147455 over = false;
3858
3859 3907648 break;
3860 }
3861 }
3862 return;
3863
3864 case 3:
3865
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5333887 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5333887 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3866 {
3867
1/2
✓ Branch 0 taken 5333887 times.
✗ Branch 1 not taken.
5333887 if (scr)
3868 {
3869
2/2
✓ Branch 0 taken 5258611 times.
✓ Branch 1 taken 75276 times.
5333887 if(base_scr->layeropacity[layer-1]!=255)
3870 75276 transp = true;
3871
3872
2/2
✓ Branch 0 taken 36654 times.
✓ Branch 1 taken 237618 times.
5333887 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3873
2/2
✓ Branch 0 taken 274272 times.
✓ Branch 1 taken 5059615 times.
5333887 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3874 237618 over = false;
3875
3876 5333887 break;
3877 }
3878 }
3879 return;
3880 }
3881
3882 int start_x, end_x, start_y, end_y;
3883 24268258 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3884
2/2
✓ Branch 0 taken 24268258 times.
✓ Branch 1 taken 257485684 times.
281753942 for (int cy = start_y; cy < end_y; cy++)
3885 {
3886
2/2
✓ Branch 0 taken 3898086039 times.
✓ Branch 1 taken 257485684 times.
4155571723 for (int cx = start_x; cx < end_x; cx++)
3887 {
3888 3898086039 int i = cx + cy*16;
3889
4/4
✓ Branch 0 taken 3441235004 times.
✓ Branch 1 taken 456851035 times.
✓ Branch 2 taken 11831072 times.
✓ Branch 3 taken 3429403932 times.
3898086039 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3890 3898086039 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3891 3898086039 }
3892 257485684 }
3893 69289652 }
3894
3895 279217603 bool lenscheck(mapscr* scr, int layer)
3896 {
3897
4/4
✓ Branch 0 taken 279041031 times.
✓ Branch 1 taken 176572 times.
✓ Branch 2 taken 176572 times.
✓ Branch 3 taken 279217603 times.
279217603 if(layer < 0 || layer > 6) return true;
3898
2/2
✓ Branch 0 taken 259374153 times.
✓ Branch 1 taken 19843450 times.
279217603 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3899 {
3900
2/2
✓ Branch 0 taken 209535949 times.
✓ Branch 1 taken 49838204 times.
259374153 if(!layer) return true;
3901
8/8
✓ Branch 0 taken 34893681 times.
✓ Branch 1 taken 174642268 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34634711 times.
✓ Branch 4 taken 146134 times.
✓ Branch 5 taken 259680 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34454309 times.
209535949 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3902 586216 return false;
3903 209096577 }
3904 else
3905 {
3906
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19843450 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 19843450 times.
19843450 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3907 return false;
3908 }
3909 228940027 return true;
3910 279041031 }
3911
3912 164988395 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3913 {
3914 164988395 bool showlayer = true;
3915 164988395 mapscr* base_scr = screen_handle.base_scr;
3916 164988395 int layer = screen_handle.layer;
3917
2/2
✓ Branch 0 taken 46541267 times.
✓ Branch 1 taken 118447128 times.
164988395 int target = type ? type : layer;
3918
3/4
✓ Branch 0 taken 118447128 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22461323 times.
✓ Branch 3 taken 24079944 times.
164988395 switch(target)
3919 {
3920 case -2:
3921
1/2
✓ Branch 0 taken 22461323 times.
✗ Branch 1 not taken.
22461323 if(!show_layer_push)
3922 showlayer = false;
3923 22461323 break;
3924
3925 case -1:
3926
1/2
✓ Branch 0 taken 24079944 times.
✗ Branch 1 not taken.
24079944 if(!show_layer_over)
3927 showlayer = false;
3928 24079944 break;
3929
3930 case 1: case 2: case 3:
3931 case 4: case 5: case 6:
3932 118447128 showlayer = show_layers[target];
3933 118447128 break;
3934 }
3935
3936
2/2
✓ Branch 0 taken 46541267 times.
✓ Branch 1 taken 118447128 times.
164988395 if(!type)
3937 {
3938
2/2
✓ Branch 0 taken 118310930 times.
✓ Branch 1 taken 136198 times.
118447128 if(!lenscheck(base_scr,layer))
3939 136198 showlayer = false;
3940 118447128 }
3941
3942
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 164852197 times.
164988395 if(showlayer)
3943 {
3944
6/6
✓ Branch 0 taken 69381600 times.
✓ Branch 1 taken 95470597 times.
✓ Branch 2 taken 24360206 times.
✓ Branch 3 taken 45021394 times.
✓ Branch 4 taken 91948 times.
✓ Branch 5 taken 24268258 times.
164852197 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3945 {
3946 69289652 do_scrolling_layer(bmp, type, screen_handle, x, y);
3947
4/4
✓ Branch 0 taken 24268258 times.
✓ Branch 1 taken 45021394 times.
✓ Branch 2 taken 22269756 times.
✓ Branch 3 taken 1998502 times.
69289652 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3948
2/2
✓ Branch 0 taken 1997926 times.
✓ Branch 1 taken 576 times.
1999078 if(mblock2.draw(bmp,layer))
3949 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3950 69289652 }
3951 164852197 }
3952 164988395 }
3953
3954 106913818 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3955 {
3956 106913818 bool showlayer = true;
3957
3958
2/4
✓ Branch 0 taken 106913818 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 106913818 times.
106913818 if(layer >= 0 && layer <= 6)
3959 {
3960 106913818 showlayer = show_layers[layer];
3961
3962
2/2
✓ Branch 0 taken 106787216 times.
✓ Branch 1 taken 126602 times.
106913818 if(!lenscheck(origin_scr,layer))
3963 126602 showlayer = false;
3964 106913818 }
3965
3966
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 106787216 times.
106913818 if (showlayer)
3967 106787216 do_primitives(bmp, layer);
3968 106913818 }
3969
3970 // Called by do_walkflags
3971 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3972 {
3973 newcombo const &c = combobuf[cmbdat];
3974
3975 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3976
3977 int32_t xx = x-xofs;
3978 int32_t yy = y+playing_field_offset-yofs;
3979
3980 int32_t bridgedetected = 0;
3981
3982 for(int32_t i=0; i<4; i++)
3983 {
3984 int32_t tx=((i&2)<<2)+xx - viewport.x;
3985 int32_t ty=((i&1)<<3)+yy - viewport.y;
3986 int32_t tx2=((i&2)<<2)+x - viewport.x;
3987 int32_t ty2=((i&1)<<3)+y - viewport.y;
3988 for (int32_t j = lyr-1; j <= 1; j++)
3989 {
3990 if (get_qr(qr_OLD_BRIDGE_COMBOS))
3991 {
3992 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
3993 {
3994 bridgedetected |= (1<<i);
3995 }
3996 }
3997 else
3998 {
3999 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
4000 {
4001 bridgedetected |= (1<<i);
4002 }
4003 }
4004 }
4005 if ((bridgedetected & (1<<i)))
4006 {
4007 if (i >= 3) break;
4008 else continue;
4009 }
4010 bool doladdercheck = true;
4011
4012 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4013 {
4014 for(int32_t k=0; k<8; k+=2)
4015 for(int32_t j=0; j<8; j+=2)
4016 if(((k+j)/2)%2)
4017 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
4018 }
4019 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4020 {
4021 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4022 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4023 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
4024 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
4025 }
4026
4027 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4028 {
4029 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4030 {
4031 for(int32_t k=0; k<8; k+=2)
4032 for(int32_t j=0; j<8; j+=2)
4033 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
4034 }
4035 else
4036 {
4037 int32_t color = makecol(178,36,36);
4038
4039 if(isstepable(cmbdat)&& (!doladdercheck))
4040 color=makecol(165,105,8);
4041 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4042 color=makecol(170,170,170);
4043
4044 rectfill(dest,tx,ty,tx+7,ty+7,color);
4045 }
4046 }
4047 }
4048
4049 // Draw damage combos
4050 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
4051 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
4052 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
4053
4054 if(dmg)
4055 {
4056 int32_t color = makecol(255,255,0);
4057 if (bridgedetected <= 0)
4058 {
4059 for(int32_t k=0; k<16; k+=2)
4060 for(int32_t j=0; j<16; j+=2)
4061 if(((k+j)/2)%2)
4062 {
4063 int32_t x0 = x - viewport.x;
4064 int32_t y0 = y - viewport.y;
4065 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
4066 }
4067 }
4068 else
4069 {
4070 for(int32_t i=0; i<4; i++)
4071 {
4072 if (!(bridgedetected & (1<<i)))
4073 {
4074 int32_t tx=((i&2)<<2)+x - viewport.x;
4075 int32_t ty=((i&1)<<3)+y - viewport.y;
4076 for(int32_t k=0; k<8; k+=2)
4077 for(int32_t j=0; j<8; j+=2)
4078 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
4079 }
4080 }
4081 }
4082 }
4083 }
4084 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4085 {
4086 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
4087 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
4088 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
4089 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
4090 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
4091 newcombo const &c = combobuf[cmbdat];
4092
4093 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
4094
4095 int32_t xx = x-viewport.x;
4096 int32_t yy = y+playing_field_offset-viewport.y;
4097
4098 int32_t bridgedetected = 0;
4099
4100 // Draw damage combos
4101 bool dmg = combo_class_buf[c.type].modify_hp_amount;
4102
4103 for(int32_t i=0; i<4; i++)
4104 {
4105 int32_t tx=((i&2)<<2)+xx;
4106 int32_t ty=((i&1)<<3)+yy;
4107 int32_t tx2=((i&2)<<2)+x;
4108 int32_t ty2=((i&1)<<3)+y;
4109 for (int32_t m = lyr-1; m <= 1; m++)
4110 {
4111 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4112 {
4113 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
4114 {
4115 bridgedetected |= (1<<i);
4116 }
4117 }
4118 else
4119 {
4120 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
4121 {
4122 bridgedetected |= (1<<i);
4123 }
4124 }
4125 }
4126 if ((bridgedetected & (1<<i)))
4127 continue;
4128 bool doladdercheck = true;
4129
4130 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4131 {
4132 for(int32_t k=0; k<8; k+=2)
4133 for(int32_t j=0; j<8; j+=2)
4134 if(((k+j)/2)%2)
4135 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4136 }
4137 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4138 {
4139 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4140 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4141 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4142 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4143 }
4144
4145 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4146 {
4147 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4148 {
4149 for(int32_t k=0; k<8; k+=2)
4150 for(int32_t j=0; j<8; j+=2)
4151 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4152 }
4153 else
4154 {
4155 ALLEGRO_COLOR* color = &col_solid;
4156
4157 if(isstepable(cmbdat)&& (!doladdercheck))
4158 color=&col_stepable;
4159 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4160 color=&col_lhook;
4161
4162 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4163 }
4164 }
4165
4166 if(dmg)
4167 {
4168 for(int32_t k=0; k<8; k+=2)
4169 for(int32_t j=0; j<8; j+=2)
4170 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4171 }
4172 }
4173 }
4174
4175 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4176 {
4177 newcombo const &c = combobuf[cmbdat];
4178
4179 int32_t xx = x-xofs-viewport.x;
4180 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4181
4182 for(int32_t i=0; i<4; i++)
4183 {
4184 int32_t tx=((i&2)<<2)+xx;
4185 int32_t ty=((i&1)<<3)+yy;
4186
4187 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4188 {
4189 int32_t color = vc(10);
4190
4191 rectfill(dest,tx,ty,tx+7,ty+7,color);
4192 }
4193 }
4194 }
4195 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4196 {
4197 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4198 newcombo const &c = combobuf[cmbdat];
4199
4200 int32_t xx = x-viewport.x;
4201 int32_t yy = y+playing_field_offset-viewport.y;
4202
4203 for(int32_t i=0; i<4; i++)
4204 {
4205 int32_t tx=((i&2)<<2)+xx;
4206 int32_t ty=((i&1)<<3)+yy;
4207
4208 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4209 {
4210 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4211 }
4212 }
4213 }
4214
4215 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4216 {
4217 for(auto cx = 0; cx < 256; cx += 16)
4218 {
4219 for(auto cy = 0; cy < 176; cy += 16)
4220 {
4221 if(isSVLadder(cx,cy))
4222 {
4223 auto nx = cx+x, ny = cy+y;
4224 if(cy && !isSVLadder(cx,cy-16))
4225 line(dest,nx,ny,nx+15,ny,c);
4226 rectfill(dest,nx,ny,nx+3,ny+15,c);
4227 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4228 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4229 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4230 }
4231 else if(isSVPlatform(cx,cy))
4232 {
4233 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4234 }
4235 }
4236 }
4237 }
4238 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4239 {
4240 for(auto cx = 0; cx < 256; cx += 16)
4241 {
4242 for(auto cy = 0; cy < 176; cy += 16)
4243 {
4244 if(isSVLadder(cx,cy))
4245 {
4246 auto nx = cx+x, ny = cy+y;
4247 if(cy && !isSVLadder(cx,cy-16))
4248 al_draw_line(nx,ny,nx+15,ny,c,1);
4249 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4250 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4251 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4252 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4253 }
4254 else if(isSVPlatform(cx,cy))
4255 {
4256 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4257 }
4258 }
4259 }
4260 }
4261
4262 // Walkflags L4 cheat
4263 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4264 {
4265 if (!show_walkflags)
4266 return;
4267
4268 start_info_bmp();
4269
4270 mapscr* scr = screen_handles[0].base_scr;
4271 for(int32_t i=0; i<176; i++)
4272 {
4273 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4274 }
4275
4276 for(int32_t k=0; k<2; k++)
4277 {
4278 scr = screen_handles[k + 1].scr;
4279
4280 if (scr)
4281 {
4282 for(int32_t i=0; i<176; i++)
4283 {
4284 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4285 }
4286 }
4287 }
4288
4289 end_info_bmp();
4290 }
4291
4292 void do_walkflags(int32_t x, int32_t y)
4293 {
4294 if (!show_walkflags)
4295 return;
4296
4297 x += -viewport.x;
4298 y += playing_field_offset - viewport.y;
4299
4300 start_info_bmp();
4301
4302 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4303 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4304 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4305
4306 end_info_bmp();
4307 }
4308
4309 // Effectflags L4 cheat
4310 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4311 {
4312 if(show_effectflags)
4313 {
4314 start_info_bmp();
4315
4316 for(int32_t i=0; i<176; i++)
4317 {
4318 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4319 }
4320
4321 end_info_bmp();
4322 }
4323 }
4324
4325 400489 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4326 {
4327 400489 int map = scr->map;
4328 400489 int screen = scr->screen;
4329
4330
2/2
✓ Branch 0 taken 2803423 times.
✓ Branch 1 taken 400489 times.
3203912 for(int32_t lyr = 0; lyr < 7; ++lyr)
4331 {
4332 2803423 mapscr* scr = get_scr_layer(map, screen, lyr);
4333
2/2
✓ Branch 0 taken 1829718 times.
✓ Branch 1 taken 973705 times.
2803423 if (!scr->is_valid()) continue;
4334
4335
2/2
✓ Branch 0 taken 322030368 times.
✓ Branch 1 taken 1829718 times.
323860086 for(int32_t q = 0; q < 176; ++q)
4336 {
4337 322030368 newcombo const& cmb = combobuf[scr->data[q]];
4338
2/2
✓ Branch 0 taken 320498295 times.
✓ Branch 1 taken 1532073 times.
322030368 if(cmb.type == cTORCH)
4339 {
4340 1532073 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4341 1532073 }
4342 322030368 }
4343 1829718 }
4344 400489 }
4345
4346 400489 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4347 {
4348 400489 word c = scr->numFFC();
4349
2/2
✓ Branch 0 taken 704965 times.
✓ Branch 1 taken 400489 times.
1105454 for(int q = 0; q < c; ++q)
4350 {
4351 704965 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4352
2/2
✓ Branch 0 taken 690157 times.
✓ Branch 1 taken 14808 times.
704965 if(cmb.type == cTORCH)
4353 {
4354 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4355 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4356 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4357 14808 }
4358 704965 }
4359 400489 }
4360
4361 struct nearby_screen_t
4362 {
4363 int screen;
4364 int offx;
4365 int offy;
4366 screen_handles_t screen_handles;
4367 };
4368 typedef std::vector<nearby_screen_t> nearby_screens_t;
4369
4370 16063482 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4371 {
4372 16063482 nearby_screens_t nearby_screens;
4373
4374 16063482 mapscr* base_scr = origin_scr;
4375
1/2
✓ Branch 0 taken 16063482 times.
✗ Branch 1 not taken.
16063482 auto& nearby_screen = nearby_screens.emplace_back();
4376 16063482 nearby_screen.screen = cur_screen;
4377
1/2
✓ Branch 0 taken 16063482 times.
✗ Branch 1 not taken.
16063482 nearby_screen.screen_handles = create_screen_handles(base_scr);
4378
4379 16063482 return nearby_screens;
4380
1/2
✓ Branch 0 taken 16063482 times.
✗ Branch 1 not taken.
16063482 }
4381
4382 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4383 {
4384 48296 nearby_screens_t nearby_screens;
4385
4386
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4387
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4388
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4389
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4390
4391
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4392
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4393
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4394
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4395
4396
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4397 {
4398
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4399 {
4400 169672 int screen = cur_screen + x + y*16;
4401
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4402
4403
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4404
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4405
4406
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4407
4408
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4409 169672 nearby_screen.screen = screen;
4410 169672 nearby_screen.offx = offx;
4411 169672 nearby_screen.offy = offy;
4412
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4413 169672 }
4414 79928 }
4415
4416 48296 return nearby_screens;
4417
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4418
4419 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4420 {
4421 3658 nearby_screens_t nearby_screens;
4422
4423
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4424
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4425
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4426
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4427
4428
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4429
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4430
4431
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4432 {
4433
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4434 {
4435 18600 int screen = -1;
4436 mapscr* base_scr;
4437 int offx, offy;
4438
4439 18600 mapscr* maze_scr = maze_state.scr;
4440 18600 int maze_screen = maze_scr->screen;
4441
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4442
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4443 18600 int maze_screen_dx = x - maze_screen_x;
4444 18600 int maze_screen_dy = y - maze_screen_y;
4445 18600 int exitdir = maze_scr->exitdir;
4446
4447 bool should_draw_maze_screen;
4448
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4449 {
4450 9548 should_draw_maze_screen = true;
4451 9548 }
4452 else
4453 {
4454 9052 should_draw_maze_screen = true;
4455
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4456
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4457
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4458 }
4459
4460
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4461 {
4462 16048 screen = maze_state.scr->screen;
4463 16048 base_scr = maze_state.scr;
4464
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4465 16048 }
4466
4467
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4468 {
4469 2552 screen = cur_screen + x + y*16;
4470
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4471
4472
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4473
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4474
4475
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4476 2552 }
4477
4478
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4479 18600 nearby_screen.screen = screen;
4480 18600 nearby_screen.offx = offx;
4481 18600 nearby_screen.offy = offy;
4482
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4483 18600 }
4484 7308 }
4485
4486 3658 return nearby_screens;
4487
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4488
4489 16115436 static nearby_screens_t get_nearby_screens()
4490 {
4491
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 16106222 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
16115436 if (maze_state.active && maze_state.loopy)
4492 3658 return get_nearby_screens_smooth_maze();
4493
4494
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 16063482 times.
16111778 if (is_in_scrolling_region())
4495 48296 return get_nearby_screens_scrolling_region();
4496
4497 16063482 return get_nearby_screens_non_scrolling_region();
4498 16115436 }
4499
4500 209727999 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4501 {
4502
2/2
✓ Branch 0 taken 211512601 times.
✓ Branch 1 taken 209727999 times.
421240600 for (auto& nearby_screen : nearby_screens)
4503 211512601 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4504 209727999 }
4505
4506 145123436 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4507 {
4508
2/2
✓ Branch 0 taken 32272366 times.
✓ Branch 1 taken 112851070 times.
145123436 if(layer != msgstr_layer) return;
4509
2/2
✓ Branch 0 taken 16114674 times.
✓ Branch 1 taken 16157692 times.
32272366 if(!dest) dest = framebuf;
4510
4511
2/2
✓ Branch 0 taken 1460393 times.
✓ Branch 1 taken 30811973 times.
32272366 if(!(msg_bg_display_buf->clip))
4512 {
4513 1460393 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4514 1460393 }
4515
4516
2/2
✓ Branch 0 taken 1460393 times.
✓ Branch 1 taken 30811973 times.
32272366 if(!(msg_portrait_display_buf->clip))
4517 {
4518 1460393 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4519 1460393 }
4520
4521
2/2
✓ Branch 0 taken 1487207 times.
✓ Branch 1 taken 30785159 times.
32272366 if(!(msg_txt_display_buf->clip))
4522 {
4523 1487207 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4524 1487207 }
4525 145123436 }
4526
4527 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4528
4529 64461744 static void set_draw_screen_clip(BITMAP* bmp)
4530 {
4531 64461744 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4532 64461744 }
4533
4534 17580 static void draw_sprites(BITMAP* dest, set<sprite*, SpriteSorter>& sprite_set, set<sprite*, SpriteSorter>::iterator& it, word upto_z)
4535 {
4536 17580 bool checkz = upto_z != word(-1); // max value represents "infinity" height
4537
6/6
✓ Branch 0 taken 11145 times.
✓ Branch 1 taken 6435 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 6275 times.
✓ Branch 4 taken 12905 times.
✓ Branch 5 taken 4675 times.
17580 if(it == sprite_set.end() || (checkz && (*it)->total_z() >= upto_z))
4538 12905 return; // no sprites to draw remaining
4539 // Just clips sprites if in a repeating, smooth maze.
4540
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 bool do_clip = maze_state.active && maze_state.loopy;
4541
4542
4543
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 if(do_clip)
4544 {
4545 int maze_screen = maze_state.scr->screen;
4546 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4547 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4548 }
4549
6/6
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 32443 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 32283 times.
✓ Branch 4 taken 4675 times.
✓ Branch 5 taken 30698 times.
67816 while(it != sprite_set.end() && (!checkz || (*it)->total_z() < upto_z))
4550 {
4551 30698 sprite* spr = *it;
4552
2/2
✓ Branch 0 taken 27768 times.
✓ Branch 1 taken 2930 times.
30698 if(spr == &Hero) // Draw the Hero
4553 {
4554 2930 decorations.draw2(dest,true);
4555 2930 Hero.draw(dest);
4556 2930 decorations.draw(dest,true);
4557
4558 // Draw enemies holding the Hero directly above the Hero
4559
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 for(int32_t i=0; i<guys.Count(); i++)
4560 {
4561 if(((enemy*)guys.spr(i))->type == eeWALK)
4562 if(((eStalfos*)guys.spr(i))->hashero)
4563 guys.spr(i)->draw(dest);
4564 else if(((enemy*)guys.spr(i))->type == eeWALLM)
4565 if(((eWallM*)guys.spr(i))->hashero)
4566 guys.spr(i)->draw(dest);
4567 }
4568 2930 }
4569
2/2
✓ Branch 0 taken 24838 times.
✓ Branch 1 taken 2930 times.
27768 else if(spr == &mblock2) // Draw the moving pushblock
4570 {
4571 2930 mblock2.draw(dest, -1);
4572 2930 do_primitives(dest, SPLAYER_MOVINGBLOCK);
4573 2930 }
4574
2/4
✓ Branch 0 taken 24838 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24838 times.
24838 else if(enemy* e = dynamic_cast<enemy*>(spr))
4575 {
4576 e->draw(dest);
4577 e->draw2(dest); // used specifically for eGleeok/esGleeok
4578 }
4579 24838 else spr->draw(dest);
4580 30698 ++it;
4581 }
4582
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 if(do_clip)
4583 clear_clip_rect(dest);
4584 17580 }
4585
4586 11991 static void draw_high_darkness(BITMAP* dest)
4587 {
4588 11991 do_primitives(dest, SPLAYER_DARKROOM_UNDER);
4589 11991 set_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
4590
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
4591 {
4592 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
4593 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
4594 }
4595
4596 11991 color_map = trans_table2;
4597
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
4598 {
4599 draw_trans_sprite(dest, darkscr_bmp, 0, 0);
4600 if(get_qr(qr_NEWDARK_TRANS_STACKING))
4601 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
4602 }
4603 else
4604 {
4605 11991 masked_blit(darkscr_bmp, dest, 0, 0, 0, 0, dest->w, dest->h);
4606 11991 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
4607 }
4608 11991 color_map = trans_table;
4609
4610 11991 set_clip_rect(dest, 0, 0, dest->w, dest->h);
4611 11991 do_primitives(dest, SPLAYER_DARKROOM_OVER);
4612 11991 }
4613
4614 16157692 static void draw_screen_post_passive_subscreen(BITMAP* dest, bool any_dark)
4615 {
4616 16157692 draw_msgstr(6, dest);
4617
4618
1/2
✓ Branch 0 taken 16157692 times.
✗ Branch 1 not taken.
16157692 if (get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
4619 draw_msgstr(6, dest);
4620
4621
6/6
✓ Branch 0 taken 1905827 times.
✓ Branch 1 taken 14251865 times.
✓ Branch 2 taken 453726 times.
✓ Branch 3 taken 1452101 times.
✓ Branch 4 taken 441735 times.
✓ Branch 5 taken 11991 times.
16157692 if (get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
4622 11991 draw_high_darkness(dest);
4623
4624 16157692 _do_current_ffc_layer(dest, 7);
4625 16157692 draw_msgstr(7, dest);
4626 16157692 }
4627
4628 // Draws to framebuf.
4629 //
4630 // But if drawPassiveSubscreenSeparate is true: framebuf_no_passive_subscreen will also contain all
4631 // draws excluding the passive subscreen.
4632 16115436 void draw_screen(bool showhero, bool runGeneric, bool drawPassiveSubscreenSeparate)
4633 {
4634 16115436 bool classic_draw = get_qr(qr_CLASSIC_DRAWING_ORDER);
4635 16115436 clear_info_bmp();
4636
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16115436 times.
16115436 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4637 {
4638 FFCore.doScriptMenuDraws();
4639 return;
4640 }
4641
4642
2/2
✓ Branch 0 taken 613245 times.
✓ Branch 1 taken 15502191 times.
16115436 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4643
4644 16115436 BITMAP* dest = framebuf;
4645 16115436 clear_bitmap(dest);
4646 16115436 clear_clip_rect(dest);
4647
4648 16115436 int32_t cmby2=0;
4649
4650 // Draw some background layers
4651 16115436 clear_bitmap(scrollbuf);
4652
4653 16115436 auto nearby_screens = get_nearby_screens();
4654
4655
2/2
✓ Branch 0 taken 16112506 times.
✓ Branch 1 taken 2930 times.
16115436 if (!classic_draw)
4656 {
4657
2/2
✓ Branch 0 taken 11720 times.
✓ Branch 1 taken 2930 times.
14650 for (int layer = -7; layer <= -4; ++layer)
4658 {
4659
1/2
✓ Branch 0 taken 11720 times.
✗ Branch 1 not taken.
11720 _do_current_ffc_layer(scrollbuf, layer);
4660
2/4
✓ Branch 0 taken 11720 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11720 times.
11720 if (script_drawing_commands.is_dirty(layer))
4661 do_primitives(scrollbuf, layer);
4662 11720 }
4663 2930 }
4664
4665 // Handle layer 2/3 possibly being background layers.
4666
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16112506 times.
16115436 if (classic_draw) // weird ordering (-3 > -2)
4667 {
4668
1/2
✓ Branch 0 taken 16112506 times.
✗ Branch 1 not taken.
32361330 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4669 16248824 mapscr* base_scr = screen_handles[0].base_scr;
4670
2/2
✓ Branch 0 taken 16106703 times.
✓ Branch 1 taken 142121 times.
16248824 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4671 142121 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4672 16248824 });
4673
4674 16112506 bool l2bg = XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG);
4675
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 15970385 times.
16112506 if (l2bg)
4676 {
4677
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 do_layer_primitives(scrollbuf, 2);
4678
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 particles.draw(scrollbuf, true, 2);
4679 142121 }
4680
1/2
✓ Branch 0 taken 16112506 times.
✗ Branch 1 not taken.
16112506 _do_current_ffc_layer(scrollbuf, -2);
4681
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 15970385 times.
16112506 if (l2bg)
4682
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 draw_msgstr(2, scrollbuf);
4683 16112506 }
4684
4685
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
32367190 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4686 16251754 mapscr* base_scr = screen_handles[0].base_scr;
4687
2/2
✓ Branch 0 taken 16017190 times.
✓ Branch 1 taken 234564 times.
16251754 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4688 234564 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4689 16251754 });
4690
4691
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 15880872 times.
16115436 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4692 {
4693
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 do_layer_primitives(scrollbuf, 3);
4694
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 particles.draw(scrollbuf, true, 3);
4695 234564 }
4696
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 _do_current_ffc_layer(scrollbuf, -3);
4697
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 15880872 times.
16115436 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4698
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 draw_msgstr(3, scrollbuf);
4699
4700
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16112506 times.
16115436 if (!classic_draw)
4701 {
4702
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -3);
4703 // Actually use proper ordering (-3 < -2)
4704
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
5860 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4705 2930 mapscr* base_scr = screen_handles[0].base_scr;
4706
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4707 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4708 2930 });
4709
4710 2930 bool l2bg = XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG);
4711
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if (l2bg)
4712 {
4713 do_layer_primitives(scrollbuf, 2);
4714 particles.draw(scrollbuf, true, 2);
4715 }
4716
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 _do_current_ffc_layer(scrollbuf, -2);
4717
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if (l2bg)
4718 draw_msgstr(2, scrollbuf);
4719
4720
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -2);
4721
4722
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 _do_current_ffc_layer(scrollbuf, -1);
4723
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -1);
4724 2930 }
4725
4726 // Draw the main combo screens ("layer 0").
4727
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
32367190 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4728 16251754 mapscr* base_scr = screen_handles[0].base_scr;
4729
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16251754 times.
16251754 if (lenscheck(base_scr, 0))
4730 {
4731 16251754 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4732 16251754 }
4733 16251754 });
4734
4735
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16115436 times.
16115436 if (lenscheck(hero_scr, 0))
4736 {
4737
2/2
✓ Branch 0 taken 466467 times.
✓ Branch 1 taken 15648969 times.
16115436 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4738
3/4
✓ Branch 0 taken 466467 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 462331 times.
470603 if(mblock2.draw(scrollbuf,0))
4739
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4740 16115436 }
4741
4742 // Lens hints, then primitives, then particles.
4743
6/10
✓ Branch 0 taken 16105407 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 16105407 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 16105407 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
16115436 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4744 {
4745
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4746
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4747 5876 }
4748
4749
2/4
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16115436 times.
✗ Branch 3 not taken.
16115436 if(show_layers[0] && lenscheck(hero_scr,0))
4750
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 do_primitives(scrollbuf, 0);
4751
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 particles.draw(scrollbuf, true, 0);
4752
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 _do_current_ffc_layer(scrollbuf, 0);
4753
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 draw_msgstr(0, scrollbuf);
4754
4755
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 set_draw_screen_clip(scrollbuf);
4756
4757 16115436 bool hero_draw_done = false;
4758
4/6
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16080684 times.
✓ Branch 3 taken 34752 times.
✓ Branch 4 taken 16080684 times.
✗ Branch 5 not taken.
16115436 bool is_cave_walking = ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom));
4759
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15772177 times.
16115436 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4760 {
4761
4/4
✓ Branch 0 taken 15770298 times.
✓ Branch 1 taken 1879 times.
✓ Branch 2 taken 88384 times.
✓ Branch 3 taken 15681914 times.
15772177 if(showhero && is_cave_walking)
4762 {
4763 88384 hero_draw_done = true;
4764
3/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34752 times.
88384 if(Hero.getAction()==climbcovertop)
4765 {
4766 34752 cmby2=16;
4767 34752 }
4768
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4769 {
4770 53632 cmby2=-16;
4771 53632 }
4772
4773
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw2(scrollbuf,true);
4774
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 Hero.draw(scrollbuf);
4775
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw(scrollbuf,true);
4776
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4777
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4778
4779
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4780
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4781
4782
4/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✓ Branch 5 taken 73152 times.
88384 if(int32_t(Hero.getX())&15)
4783 {
4784
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4785
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4786 15232 }
4787 88384 }
4788 15772177 }
4789
4790
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 16115436 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16115436 if (get_qr(qr_HERO_DIVE_UNDER_LAYER_1) && Hero.isDiving())
4791 {
4792 Hero.draw_under(scrollbuf);
4793 decorations.draw2(scrollbuf,true);
4794 Hero.draw(scrollbuf);
4795 decorations.draw(scrollbuf,true);
4796 hero_draw_done = true;
4797 }
4798
4799
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
32367190 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4800 16251754 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4801 16251754 });
4802
4803
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 do_layer_primitives(scrollbuf, 1);
4804
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 particles.draw(scrollbuf, true, 1);
4805
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 _do_current_ffc_layer(scrollbuf, 1);
4806
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 draw_msgstr(1, scrollbuf);
4807
4808 // Handle layer 2 NOT being used as background layers.
4809
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
32367190 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4810 16251754 mapscr* base_scr = screen_handles[0].base_scr;
4811
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 16109633 times.
16251754 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4812 16109633 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4813 16251754 });
4814
4815
2/2
✓ Branch 0 taken 15973315 times.
✓ Branch 1 taken 142121 times.
16115436 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4816 {
4817
1/2
✓ Branch 0 taken 15973315 times.
✗ Branch 1 not taken.
15973315 do_layer_primitives(scrollbuf, 2);
4818
1/2
✓ Branch 0 taken 15973315 times.
✗ Branch 1 not taken.
15973315 particles.draw(scrollbuf, true, 2);
4819 15973315 }
4820
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 _do_current_ffc_layer(scrollbuf, 2);
4821
2/2
✓ Branch 0 taken 15973315 times.
✓ Branch 1 taken 142121 times.
16115436 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4822
1/2
✓ Branch 0 taken 15973315 times.
✗ Branch 1 not taken.
15973315 draw_msgstr(2, scrollbuf);
4823
4824
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4825
4826
2/2
✓ Branch 0 taken 15772177 times.
✓ Branch 1 taken 343259 times.
16115436 if(get_qr(qr_LAYER12UNDERCAVE))
4827 {
4828
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
343259 if(showhero && is_cave_walking)
4829 {
4830 hero_draw_done = true;
4831 if(Hero.getAction()==climbcovertop)
4832 {
4833 cmby2=16;
4834 }
4835 else if(Hero.getAction()==climbcoverbottom)
4836 {
4837 cmby2=-16;
4838 }
4839
4840 decorations.draw2(scrollbuf,true);
4841 Hero.draw(scrollbuf);
4842 decorations.draw(scrollbuf,true);
4843 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4844 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4845
4846 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4847 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4848
4849 if(int32_t(Hero.getX())&15)
4850 {
4851 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4852 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4853 }
4854 }
4855 343259 }
4856
4857
2/2
✓ Branch 0 taken 466467 times.
✓ Branch 1 taken 15648969 times.
16115436 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4858 {
4859
1/2
✓ Branch 0 taken 15648969 times.
✗ Branch 1 not taken.
31434256 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4860 15785287 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4861
2/2
✓ Branch 0 taken 14460567 times.
✓ Branch 1 taken 1324720 times.
15785287 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4862 {
4863 1324720 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4864 1324720 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4865 1324720 }
4866 15785287 });
4867
4868
1/2
✓ Branch 0 taken 15648969 times.
✗ Branch 1 not taken.
15648969 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4869 15648969 }
4870
4871 // Show walkflags cheat
4872
2/4
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16115436 times.
16115436 if (show_walkflags || show_effectflags)
4873 {
4874 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4875 do_walkflags(screen_handles, offx, offy);
4876 do_effectflags(screen_handles[0].base_scr, offx, offy);
4877 });
4878
4879 do_walkflags(0, 0);
4880 }
4881
4882
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4883
4884 // Lens hints, doors etc.
4885
4/8
✓ Branch 0 taken 16105407 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 16105407 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 16105407 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
16115436 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4886 {
4887
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4888 {
4889
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4890
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4891 4153 }
4892
4893
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4894
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4895 10029 }
4896
4897 // Blit those layers onto dest (framebuf)
4898
4899
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 set_draw_screen_clip(dest);
4900
4901
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 blit(scrollbuf, dest, 0, 0, 0, 0, 256, 232);
4902
4903 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4904 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4905
4906 // Draw the subscreen, without clipping
4907
2/2
✓ Branch 0 taken 9233036 times.
✓ Branch 1 taken 6882400 times.
16115436 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4908 {
4909 9233036 bool dotime = false;
4910
4/6
✓ Branch 0 taken 9233036 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3412853 times.
✓ Branch 3 taken 5820183 times.
✓ Branch 4 taken 3412853 times.
✗ Branch 5 not taken.
9233036 if (replay_version_check(22)) dotime = game->should_show_time();
4911
1/2
✓ Branch 0 taken 9233036 times.
✗ Branch 1 not taken.
9233036 put_passive_subscr(dest, 0, 0, dotime, sspUP);
4912 9233036 }
4913
4914 // Draw some sprites onto dest
4915
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 set_clip_rect(dest,0,0,256,232);
4916
4917
2/2
✓ Branch 0 taken 99299 times.
✓ Branch 1 taken 16016137 times.
16115436 if(!(pricesdisplaybuf->clip))
4918 {
4919
1/2
✓ Branch 0 taken 99299 times.
✗ Branch 1 not taken.
99299 masked_blit(pricesdisplaybuf,dest,0,0,0,playing_field_offset,256,176);
4920 99299 }
4921
4922
5/6
✓ Branch 0 taken 16069810 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16063482 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16115436 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4923 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
4924
4925
4/4
✓ Branch 0 taken 16113557 times.
✓ Branch 1 taken 1879 times.
✓ Branch 2 taken 16025173 times.
✓ Branch 3 taken 88384 times.
16115436 if(showhero && !hero_draw_done)
4926 {
4927
1/2
✓ Branch 0 taken 16025173 times.
✗ Branch 1 not taken.
16025173 Hero.draw_under(dest);
4928
4929
3/4
✓ Branch 0 taken 16025173 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141385 times.
✓ Branch 3 taken 15883788 times.
16025173 if(Hero.isSwimming())
4930 {
4931
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw2(dest,true);
4932
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 Hero.draw(dest);
4933
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw(dest,true);
4934 141385 hero_draw_done = true;
4935 141385 }
4936 16025173 }
4937
4938 16115436 set<sprite*, SpriteSorter> sorted_sprites;
4939 16115436 vector<sprite*> temp_sprites;
4940 16115436 std::function<bool(sprite&)> add_sprite = [&](sprite& spr)
4941 {
4942 sorted_sprites.insert(&spr);
4943 return false;
4944 };
4945
4946
2/2
✓ Branch 0 taken 16112506 times.
✓ Branch 1 taken 2930 times.
16115436 if (classic_draw)
4947 {
4948
2/2
✓ Branch 0 taken 26031 times.
✓ Branch 1 taken 16086475 times.
16112506 if(drawguys)
4949 {
4950
4/4
✓ Branch 0 taken 1964390 times.
✓ Branch 1 taken 14122085 times.
✓ Branch 2 taken 981955 times.
✓ Branch 3 taken 982435 times.
16086475 if(get_qr(qr_NOFLICKER) || (frame&1))
4951 {
4952 // Just clips sprites if in a repeating, smooth maze.
4953
2/2
✓ Branch 0 taken 15094826 times.
✓ Branch 1 taken 9214 times.
15104040 bool do_clip = maze_state.active && maze_state.loopy;
4954
4955
1/2
✓ Branch 0 taken 15104040 times.
✗ Branch 1 not taken.
15104040 if(!get_qr(qr_OLD_WEAPON_DRAW_ANIMATE_TIMING))
4956 {
4957 if (do_clip)
4958 {
4959 Ewpns.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS));
4960 Lwpns.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS));
4961 }
4962 else
4963 {
4964 Ewpns.drawshadow(dest,get_qr(qr_TRANSSHADOWS),true);
4965 Lwpns.drawshadow(dest,get_qr(qr_TRANSSHADOWS),true);
4966 }
4967 }
4968
3/4
✓ Branch 0 taken 24902769 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9798729 times.
✓ Branch 3 taken 15104040 times.
24902769 for(int32_t i=0; i<Ewpns.Count(); i++)
4969 {
4970
3/4
✓ Branch 0 taken 9798729 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 250942 times.
✓ Branch 3 taken 9547787 times.
9798729 if(((weapon *)Ewpns.spr(i))->behind)
4971
2/4
✓ Branch 0 taken 250942 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 250942 times.
✗ Branch 3 not taken.
250942 Ewpns.spr(i)->draw(dest);
4972 9798729 }
4973
1/2
✓ Branch 0 taken 15104040 times.
✗ Branch 1 not taken.
15104040 do_primitives(dest, SPLAYER_EWEAP_BEHIND_DRAW);
4974
4975
3/4
✓ Branch 0 taken 21286196 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6182156 times.
✓ Branch 3 taken 15104040 times.
21286196 for(int32_t i=0; i<Lwpns.Count(); i++)
4976 {
4977
3/4
✓ Branch 0 taken 6182156 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1206996 times.
✓ Branch 3 taken 4975160 times.
6182156 if(((weapon *)Lwpns.spr(i))->behind)
4978
2/4
✓ Branch 0 taken 1206996 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1206996 times.
✗ Branch 3 not taken.
1206996 Lwpns.spr(i)->draw(dest);
4979 6182156 }
4980
1/2
✓ Branch 0 taken 15104040 times.
✗ Branch 1 not taken.
15104040 do_primitives(dest, SPLAYER_LWEAP_BEHIND_DRAW);
4981
4982
6/6
✓ Branch 0 taken 10376310 times.
✓ Branch 1 taken 4727730 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 9028010 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
15104040 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4983 {
4984
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9698363 times.
9702021 if (do_clip)
4985
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS)!=0);
4986 else
4987
1/2
✓ Branch 0 taken 9698363 times.
✗ Branch 1 not taken.
9698363 guys.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0,true);
4988 9702021 }
4989
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15100382 times.
15104040 if (do_clip)
4990
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(dest);
4991 else
4992
1/2
✓ Branch 0 taken 15100382 times.
✗ Branch 1 not taken.
15100382 guys.draw(dest,true);
4993
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15100382 times.
15104040 if (do_clip)
4994 {
4995 3658 int maze_screen = maze_state.scr->screen;
4996
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4997
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4998 3658 }
4999
1/2
✓ Branch 0 taken 15104040 times.
✗ Branch 1 not taken.
15104040 do_primitives(dest, SPLAYER_NPC_DRAW);
5000
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15100382 times.
15104040 if (do_clip)
5001
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(dest);
5002
5003
1/2
✓ Branch 0 taken 15104040 times.
✗ Branch 1 not taken.
15104040 chainlinks.draw(dest,true);
5004
1/2
✓ Branch 0 taken 15104040 times.
✗ Branch 1 not taken.
15104040 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5005 //Lwpns.draw(dest,true);
5006
5007
3/4
✓ Branch 0 taken 24902769 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9798729 times.
✓ Branch 3 taken 15104040 times.
24902769 for(int32_t i=0; i<Ewpns.Count(); i++)
5008 {
5009
3/4
✓ Branch 0 taken 9798729 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9547787 times.
✓ Branch 3 taken 250942 times.
9798729 if(!((weapon *)Ewpns.spr(i))->behind)
5010
2/4
✓ Branch 0 taken 9547787 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9547787 times.
✗ Branch 3 not taken.
9547787 Ewpns.spr(i)->draw(dest);
5011 9798729 }
5012
1/2
✓ Branch 0 taken 15104040 times.
✗ Branch 1 not taken.
15104040 do_primitives(dest, SPLAYER_EWEAP_FRONT_DRAW);
5013
5014
3/4
✓ Branch 0 taken 21286196 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6182156 times.
✓ Branch 3 taken 15104040 times.
21286196 for(int32_t i=0; i<Lwpns.Count(); i++)
5015 {
5016
3/4
✓ Branch 0 taken 6182156 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4975160 times.
✓ Branch 3 taken 1206996 times.
6182156 if(!((weapon *)Lwpns.spr(i))->behind)
5017
2/4
✓ Branch 0 taken 4975160 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4975160 times.
✗ Branch 3 not taken.
4975160 Lwpns.spr(i)->draw(dest);
5018 6182156 }
5019
1/2
✓ Branch 0 taken 15104040 times.
✗ Branch 1 not taken.
15104040 do_primitives(dest, SPLAYER_LWEAP_FRONT_DRAW);
5020
5021
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15100382 times.
15104040 if (do_clip)
5022
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(dest);
5023 else
5024
1/2
✓ Branch 0 taken 15100382 times.
✗ Branch 1 not taken.
15100382 items.draw(dest,true);
5025
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15100382 times.
15104040 if (do_clip)
5026 {
5027 3658 int maze_screen = maze_state.scr->screen;
5028
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
5029
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
5030 3658 }
5031
1/2
✓ Branch 0 taken 15104040 times.
✗ Branch 1 not taken.
15104040 do_primitives(dest, SPLAYER_ITEMSPRITE_DRAW);
5032
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15100382 times.
15104040 if (do_clip)
5033
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(dest);
5034 15104040 }
5035 else
5036 {
5037
3/4
✓ Branch 0 taken 1481463 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 499028 times.
✓ Branch 3 taken 982435 times.
1481463 for(int32_t i=0; i<Ewpns.Count(); i++)
5038 {
5039
3/4
✓ Branch 0 taken 499028 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 490383 times.
499028 if(((weapon *)Ewpns.spr(i))->behind)
5040
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(dest);
5041 499028 }
5042
1/2
✓ Branch 0 taken 982435 times.
✗ Branch 1 not taken.
982435 do_primitives(dest, SPLAYER_EWEAP_BEHIND_DRAW);
5043
5044
3/4
✓ Branch 0 taken 1211738 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 229303 times.
✓ Branch 3 taken 982435 times.
1211738 for(int32_t i=0; i<Lwpns.Count(); i++)
5045 {
5046
2/4
✓ Branch 0 taken 229303 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 229303 times.
229303 if(((weapon *)Lwpns.spr(i))->behind)
5047 Lwpns.spr(i)->draw(dest);
5048 229303 }
5049
1/2
✓ Branch 0 taken 982435 times.
✗ Branch 1 not taken.
982435 do_primitives(dest, SPLAYER_LWEAP_BEHIND_DRAW);
5050
5051
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 753815 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
982435 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5052 {
5053
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0,true);
5054 228620 }
5055
5056
1/2
✓ Branch 0 taken 982435 times.
✗ Branch 1 not taken.
982435 items.draw(dest,false);
5057
1/2
✓ Branch 0 taken 982435 times.
✗ Branch 1 not taken.
982435 do_primitives(dest, SPLAYER_ITEMSPRITE_DRAW);
5058
1/2
✓ Branch 0 taken 982435 times.
✗ Branch 1 not taken.
982435 chainlinks.draw(dest,false);
5059
1/2
✓ Branch 0 taken 982435 times.
✗ Branch 1 not taken.
982435 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5060 //Lwpns.draw(dest,false);
5061
1/2
✓ Branch 0 taken 982435 times.
✗ Branch 1 not taken.
982435 guys.draw(dest,false);
5062
1/2
✓ Branch 0 taken 982435 times.
✗ Branch 1 not taken.
982435 do_primitives(dest, SPLAYER_NPC_DRAW);
5063
5064
3/4
✓ Branch 0 taken 1481463 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 499028 times.
✓ Branch 3 taken 982435 times.
1481463 for(int32_t i=0; i<Ewpns.Count(); i++)
5065 {
5066
3/4
✓ Branch 0 taken 499028 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 490383 times.
✓ Branch 3 taken 8645 times.
499028 if(!((weapon *)Ewpns.spr(i))->behind)
5067 {
5068
2/4
✓ Branch 0 taken 490383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 490383 times.
✗ Branch 3 not taken.
490383 Ewpns.spr(i)->draw(dest);
5069 490383 }
5070 499028 }
5071
1/2
✓ Branch 0 taken 982435 times.
✗ Branch 1 not taken.
982435 do_primitives(dest, SPLAYER_EWEAP_FRONT_DRAW);
5072
5073
3/4
✓ Branch 0 taken 1211738 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 229303 times.
✓ Branch 3 taken 982435 times.
1211738 for(int32_t i=0; i<Lwpns.Count(); i++)
5074 {
5075
2/4
✓ Branch 0 taken 229303 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 229303 times.
✗ Branch 3 not taken.
229303 if(!((weapon *)Lwpns.spr(i))->behind)
5076 {
5077
2/4
✓ Branch 0 taken 229303 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 229303 times.
✗ Branch 3 not taken.
229303 Lwpns.spr(i)->draw(dest);
5078 229303 }
5079 229303 }
5080
1/2
✓ Branch 0 taken 982435 times.
✗ Branch 1 not taken.
982435 do_primitives(dest, SPLAYER_LWEAP_FRONT_DRAW);
5081 }
5082
5083
1/2
✓ Branch 0 taken 16086475 times.
✗ Branch 1 not taken.
16086475 guys.draw2(dest,true);
5084 16086475 }
5085
5086
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16112506 times.
16112506 if(mirror_portal.destdmap > -1)
5087 mirror_portal.draw(dest);
5088
1/2
✓ Branch 0 taken 16112506 times.
✗ Branch 1 not taken.
16112506 portals.draw(dest,true);
5089
5090
4/4
✓ Branch 0 taken 16110627 times.
✓ Branch 1 taken 1879 times.
✓ Branch 2 taken 88384 times.
✓ Branch 3 taken 16022243 times.
16112506 if(showhero && !is_cave_walking)
5091 {
5092
2/2
✓ Branch 0 taken 15562193 times.
✓ Branch 1 taken 460050 times.
16022243 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
5093 {
5094
1/2
✓ Branch 0 taken 15562193 times.
✗ Branch 1 not taken.
15562193 mblock2.draw(dest,-1);
5095
1/2
✓ Branch 0 taken 15562193 times.
✗ Branch 1 not taken.
15562193 do_primitives(dest, SPLAYER_MOVINGBLOCK);
5096 15562193 }
5097
2/2
✓ Branch 0 taken 15880858 times.
✓ Branch 1 taken 141385 times.
16022243 if(!hero_draw_done)
5098 {
5099
8/12
✓ Branch 0 taken 15880858 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15880858 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15861688 times.
✓ Branch 5 taken 19170 times.
✓ Branch 6 taken 15861688 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15861688 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15879488 times.
15880858 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5100 {
5101
2/2
✓ Branch 0 taken 18485 times.
✓ Branch 1 taken 15862373 times.
15880858 Hero.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0);
5102 18485 }
5103
5104
6/8
✓ Branch 0 taken 15880858 times.
✓ Branch 1 taken 15862373 times.
✓ Branch 2 taken 15880858 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15880858 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15866794 times.
✓ Branch 7 taken 14064 times.
18485 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
5105 {
5106
1/2
✓ Branch 0 taken 15866794 times.
✗ Branch 1 not taken.
15866794 decorations.draw2(dest,true);
5107
1/2
✓ Branch 0 taken 15866794 times.
✗ Branch 1 not taken.
15866794 Hero.draw(dest);
5108
1/2
✓ Branch 0 taken 15866794 times.
✗ Branch 1 not taken.
15866794 decorations.draw(dest,true);
5109 15866794 hero_draw_done = true;
5110 15866794 }
5111 15880858 }
5112 16022243 }
5113
5114
3/4
✓ Branch 0 taken 56459141 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40346635 times.
✓ Branch 3 taken 16112506 times.
56459141 for(int32_t i=0; i<guys.Count(); i++)
5115 {
5116
3/4
✓ Branch 0 taken 40346635 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16478267 times.
✓ Branch 3 taken 23868368 times.
40346635 if(((enemy*)guys.spr(i))->type == eeWALK)
5117 {
5118
3/4
✓ Branch 0 taken 16478267 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7965 times.
✓ Branch 3 taken 16470302 times.
16478267 if(((eStalfos*)guys.spr(i))->hashero)
5119 {
5120
2/4
✓ Branch 0 taken 7965 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7965 times.
✗ Branch 3 not taken.
7965 guys.spr(i)->draw(dest);
5121 7965 }
5122 16478267 }
5123
5124
3/4
✓ Branch 0 taken 40346635 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 506384 times.
✓ Branch 3 taken 39840251 times.
40346635 if(((enemy*)guys.spr(i))->type == eeWALLM)
5125 {
5126
3/4
✓ Branch 0 taken 506384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 505055 times.
506384 if(((eWallM*)guys.spr(i))->hashero)
5127 {
5128
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(dest);
5129 1329 }
5130 506384 }
5131
5132
11/20
✓ Branch 0 taken 40346635 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40346635 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40346635 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 40346635 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 40346635 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 40346635 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 40346635 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 40346635 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 40346635 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1523506 times.
✓ Branch 19 taken 38823129 times.
40346635 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
5133 {
5134 //Jumping enemies in front of Hero.
5135
2/4
✓ Branch 0 taken 1523506 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1523506 times.
✗ Branch 3 not taken.
1523506 guys.spr(i)->draw(dest);
5136 1523506 }
5137
1/2
✓ Branch 0 taken 40346635 times.
✗ Branch 1 not taken.
40346635 do_primitives(dest, SPLAYER_NPC_ABOVEPLAYER_DRAW);
5138 40346635 }
5139 16112506 }
5140 else
5141 {
5142
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if(drawguys)
5143 {
5144
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 chainlinks.forEach(add_sprite);
5145
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
5860 bool show_enemy_shadows = (get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1));
5146 25837 auto add_spr_shadow = [&](sprite& spr)
5147 {
5148 22907 sorted_sprites.insert(&spr);
5149
3/4
✓ Branch 0 taken 1291 times.
✓ Branch 1 taken 21616 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1291 times.
22907 if(spr.total_z() > 0 && spr.can_drawshadow())
5150 {
5151
1/2
✓ Branch 0 taken 1291 times.
✗ Branch 1 not taken.
1291 tempsprite_shadow* shadow = new tempsprite_shadow(&spr);
5152 1291 sorted_sprites.insert(shadow);
5153 1291 temp_sprites.push_back(shadow);
5154 1291 }
5155 22907 return false;
5156 };
5157
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 Lwpns.forEach(add_spr_shadow);
5158
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 Ewpns.forEach(add_spr_shadow);
5159
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 items.forEach(add_spr_shadow);
5160
4/14
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2930 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2930 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2930 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2930 guys.forEach(show_enemy_shadows ? add_spr_shadow : add_sprite);
5161 2930 }
5162
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 if(showhero && !hero_draw_done)
5163 {
5164
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 sorted_sprites.insert(&Hero);
5165
9/14
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2290 times.
✓ Branch 5 taken 640 times.
✓ Branch 6 taken 2290 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2290 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2930 times.
✓ Branch 12 taken 2290 times.
✓ Branch 13 taken 2290 times.
2930 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5166 {
5167
3/4
✓ Branch 0 taken 640 times.
✓ Branch 1 taken 4580 times.
✓ Branch 2 taken 640 times.
✗ Branch 3 not taken.
5220 tempsprite_shadow* shadow = new tempsprite_shadow(&Hero);
5168
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 sorted_sprites.insert(shadow);
5169
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 temp_sprites.push_back(shadow);
5170 640 }
5171 2930 }
5172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if(mirror_portal.destdmap > -1)
5173 sorted_sprites.insert(&mirror_portal);
5174
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 portals.forEach(add_sprite);
5175
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
5176
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 sorted_sprites.insert(&mblock2);
5177 }
5178 16115436 auto sprite_it = sorted_sprites.begin();
5179
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16112506 times.
16115436 if (!classic_draw)
5180
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_GROUND]);
5181
5182 // Draw some layers onto dest
5183
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 set_draw_screen_clip(dest);
5184
5/6
✓ Branch 0 taken 16069810 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16063482 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16115436 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5185 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5186
5187 // Handle layer 3 NOT being used as background layers.
5188
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
32367190 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5189 16251754 mapscr* base_scr = screen_handles[0].base_scr;
5190
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 16017190 times.
16251754 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5191 16017190 do_layer(dest, 0, screen_handles[3], offx, offy);
5192 16251754 });
5193
5194
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16112506 times.
16115436 if (!classic_draw)
5195
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_3]);
5196
5197
2/2
✓ Branch 0 taken 15880872 times.
✓ Branch 1 taken 234564 times.
16115436 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5198 {
5199
1/2
✓ Branch 0 taken 15880872 times.
✗ Branch 1 not taken.
15880872 do_layer_primitives(dest, 3);
5200
1/2
✓ Branch 0 taken 15880872 times.
✗ Branch 1 not taken.
15880872 particles.draw(dest, true, 3);
5201 15880872 }
5202
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 _do_current_ffc_layer(dest, 3);
5203
2/2
✓ Branch 0 taken 15880872 times.
✓ Branch 1 taken 234564 times.
16115436 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5204
1/2
✓ Branch 0 taken 15880872 times.
✗ Branch 1 not taken.
15880872 draw_msgstr(3);
5205
5206
5207
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
32367190 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5208 16251754 do_layer(dest, 0, screen_handles[4], offx, offy);
5209 16251754 });
5210
5211
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16112506 times.
16115436 if (!classic_draw)
5212
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_4]);
5213
5214
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 do_layer_primitives(dest, 4);
5215
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 particles.draw(dest, true, 4);
5216
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 _do_current_ffc_layer(dest, 4);
5217
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 draw_msgstr(4);
5218
5219
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
32367190 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5220 16251754 do_layer(dest, -1, screen_handles[0], offx, offy);
5221
2/2
✓ Branch 0 taken 14384400 times.
✓ Branch 1 taken 1867354 times.
16251754 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
5222 {
5223 1867354 do_layer(dest, -1, screen_handles[1], offx, offy);
5224 1867354 do_layer(dest, -1, screen_handles[2], offx, offy);
5225 1867354 }
5226 16251754 });
5227
5228
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 do_primitives(dest, SPLAYER_OVERHEAD_CMB);
5229
5230 // Draw some flying sprites onto dest
5231
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 clear_clip_rect(dest);
5232
5/6
✓ Branch 0 taken 16069810 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16063482 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16115436 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5233 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5234
5235
2/2
✓ Branch 0 taken 16112506 times.
✓ Branch 1 taken 2930 times.
16115436 if (classic_draw)
5236 {
5237 //Jumping Hero and jumping enemies are drawn on this layer.
5238
5/8
✓ Branch 0 taken 16112506 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16112506 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16112506 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14064 times.
✓ Branch 7 taken 16098442 times.
16112506 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
5239 {
5240
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw2(dest,false);
5241
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 Hero.draw(dest);
5242
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 chainlinks.draw(dest,true);
5243
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5244
5245
3/4
✓ Branch 0 taken 16806 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 14064 times.
16806 for(int32_t i=0; i<Lwpns.Count(); i++)
5246 {
5247
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
5248 {
5249
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(dest);
5250 239 }
5251 2742 }
5252
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(dest, SPLAYER_LWEAP_ABOVE_DRAW);
5253
5254
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw(dest,false);
5255 14064 }
5256
5257
5/6
✓ Branch 0 taken 3872989 times.
✓ Branch 1 taken 12239517 times.
✓ Branch 2 taken 44252175 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32012658 times.
✓ Branch 5 taken 12239517 times.
48125164 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
5258 {
5259
13/22
✓ Branch 0 taken 32012658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32012658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27108201 times.
✓ Branch 5 taken 4904457 times.
✓ Branch 6 taken 27108201 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27108201 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27108201 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27108201 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27108201 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27108201 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27108201 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27101633 times.
32012658 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
5260 {
5261
2/4
✓ Branch 0 taken 4911025 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4911025 times.
✗ Branch 3 not taken.
4911025 guys.spr(i)->draw(dest);
5262 4911025 }
5263 44252175 }
5264 else
5265 {
5266
3/4
✓ Branch 0 taken 12206966 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8333977 times.
✓ Branch 3 taken 3872989 times.
12206966 for(int32_t i=0; i<guys.Count(); i++)
5267 {
5268
13/22
✓ Branch 0 taken 8333977 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8333977 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6997572 times.
✓ Branch 5 taken 1336405 times.
✓ Branch 6 taken 6997572 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6997572 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6997572 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6478745 times.
✓ Branch 13 taken 518827 times.
✓ Branch 14 taken 6478745 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 6478745 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6478745 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 6478745 times.
8333977 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
5269 {
5270
2/4
✓ Branch 0 taken 1855232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1855232 times.
✗ Branch 3 not taken.
1855232 guys.spr(i)->draw(dest);
5271 1855232 }
5272 8333977 }
5273 }
5274
1/2
✓ Branch 0 taken 16112506 times.
✗ Branch 1 not taken.
16112506 do_primitives(dest, SPLAYER_NPC_AIRBORNE_DRAW);
5275 16112506 }
5276
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 else draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_OVERHEAD]);
5277
5278 // Draw the Moving Fairy above layer 3
5279
3/4
✓ Branch 0 taken 19435229 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3319793 times.
✓ Branch 3 taken 16115436 times.
19435229 for(int32_t i=0; i<items.Count(); i++)
5280
6/8
✓ Branch 0 taken 3319793 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 70001 times.
✓ Branch 3 taken 3249792 times.
✓ Branch 4 taken 70001 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60287 times.
✓ Branch 7 taken 9714 times.
3380080 if(itemsbuf[items.spr(i)->id].type == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
5281
2/4
✓ Branch 0 taken 60287 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60287 times.
✗ Branch 3 not taken.
60287 items.spr(i)->draw(dest);
5282
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 do_primitives(dest, SPLAYER_FAIRYITEM_DRAW);
5283
5284 // Draw some layers onto dest
5285
5286
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 set_draw_screen_clip(dest);
5287
5288
2/2
✓ Branch 0 taken 16101084 times.
✓ Branch 1 taken 14352 times.
16115436 if (lightbeam_present)
5289 {
5290 14352 color_map = trans_table2;
5291
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
5292
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(dest, lightbeam_bmp, 0, playing_field_offset);
5293 else
5294
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, dest, 0, 0, 0, playing_field_offset, 256, 176);
5295 14352 color_map = trans_table;
5296 14352 }
5297
5298
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
32367190 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5299 16251754 do_layer(dest, 0, screen_handles[5], offx, offy);
5300 16251754 });
5301
5302
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16112506 times.
16115436 if (!classic_draw)
5303
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_5]);
5304
5305
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 do_layer_primitives(dest, 5);
5306
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 particles.draw(dest, true, 5);
5307
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 _do_current_ffc_layer(dest, 5);
5308
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 draw_msgstr(5);
5309
5310
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 _do_current_ffc_layer(dest, -1000); // 'overhead' freeform combos
5311
5312
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 do_primitives(dest, SPLAYER_OVERHEAD_FFC);
5313
5314
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
32367190 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5315 16251754 do_layer(dest, 0, screen_handles[6], offx, offy);
5316 16251754 });
5317
5318
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16112506 times.
16115436 if (!classic_draw)
5319
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, word(-1));
5320
5321
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 do_layer_primitives(dest, 6);
5322
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 particles.draw(dest, true, 6);
5323
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 _do_current_ffc_layer(dest, 6);
5324
5325 16115436 bool any_dark = false;
5326
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
32367190 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5327 16251754 mapscr* base_scr = screen_handles[0].base_scr;
5328 16251754 any_dark |= is_dark(base_scr);
5329 16251754 });
5330
5331 // Handle low drawn darkness
5332
4/4
✓ Branch 0 taken 1863571 times.
✓ Branch 1 taken 14251865 times.
✓ Branch 2 taken 1516672 times.
✓ Branch 3 taken 346899 times.
16115436 if(get_qr(qr_NEW_DARKROOM) && any_dark)
5333 {
5334
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
700032 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5335 353133 mapscr* base_scr = screen_handles[0].base_scr;
5336 353133 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
5337 353133 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
5338 353133 });
5339
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
346899 if(showhero)
5340
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
346899 Hero.calc_darkroom_hero(0, -playing_field_offset);
5341
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
700032 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5342 353133 mapscr* base_scr = screen_handles[0].base_scr;
5343
2/2
✓ Branch 0 taken 348403 times.
✓ Branch 1 taken 4730 times.
353133 if (!is_dark(base_scr))
5344 {
5345 4730 offy += playing_field_offset;
5346 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5347 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5348 4730 }
5349 353133 });
5350 346899 }
5351
5352 //Darkroom if under the subscreen
5353
6/6
✓ Branch 0 taken 1863571 times.
✓ Branch 1 taken 14251865 times.
✓ Branch 2 taken 1409845 times.
✓ Branch 3 taken 453726 times.
✓ Branch 4 taken 334908 times.
✓ Branch 5 taken 1074937 times.
16115436 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
5354 {
5355
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 do_primitives(dest, SPLAYER_DARKROOM_UNDER);
5356
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 set_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5357
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 334908 times.
334908 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5358 {
5359 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5360 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5361 }
5362
5363 334908 color_map = trans_table2;
5364
2/2
✓ Branch 0 taken 15523 times.
✓ Branch 1 taken 319385 times.
334908 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5365 {
5366
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 draw_trans_sprite(dest, darkscr_bmp, 0, 0);
5367
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5368
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
5369 15523 }
5370 else
5371 {
5372
1/2
✓ Branch 0 taken 319385 times.
✗ Branch 1 not taken.
319385 masked_blit(darkscr_bmp, dest, 0, 0, 0, 0, dest->w, dest->h);
5373
1/2
✓ Branch 0 taken 319385 times.
✗ Branch 1 not taken.
319385 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
5374 }
5375 334908 color_map = trans_table;
5376
5377
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 set_clip_rect(dest, 0, 0, dest->w, dest->h);
5378
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 do_primitives(dest, SPLAYER_DARKROOM_OVER);
5379 334908 }
5380
5381
3/6
✓ Branch 0 taken 51954 times.
✓ Branch 1 taken 16063482 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 51954 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16115436 if (is_in_scrolling_region() && lensclk && !FFCore.system_suspend[susptLENS])
5382 {
5383 draw_lens_over(dest);
5384 --lensclk;
5385 }
5386
5387 // Draw some text on dest
5388
5389
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 set_clip_rect(dest,0,0,256,232);
5390
5391
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5392
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 draw_msgstr(6);
5393
5394 // Draw the subscreen, without clipping
5395
2/2
✓ Branch 0 taken 6882400 times.
✓ Branch 1 taken 9233036 times.
16115436 if(get_qr(qr_SUBSCREENOVERSPRITES))
5396 {
5397
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 6840144 times.
6882400 if (drawPassiveSubscreenSeparate)
5398
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 blit(dest, framebuf_no_passive_subscreen, 0, 0, 0, 0, dest->w, dest->h);
5399
5400
2/4
✓ Branch 0 taken 6882400 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6882400 times.
✗ Branch 3 not taken.
6882400 put_passive_subscr(dest, 0, 0, game->should_show_time(), sspUP);
5401
5402
1/2
✓ Branch 0 taken 6882400 times.
✗ Branch 1 not taken.
6882400 do_primitives(dest, 7);
5403
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 6840144 times.
6882400 if (drawPassiveSubscreenSeparate)
5404
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 do_primitives(framebuf_no_passive_subscreen, 7);
5405 6882400 }
5406
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9233036 times.
9233036 else if (!classic_draw)
5407 do_primitives(dest, 7);
5408
5409
1/2
✓ Branch 0 taken 16115436 times.
✗ Branch 1 not taken.
16115436 draw_screen_post_passive_subscreen(dest, any_dark);
5410
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 16073180 times.
16115436 if (drawPassiveSubscreenSeparate)
5411
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 draw_screen_post_passive_subscreen(framebuf_no_passive_subscreen, any_dark);
5412
5413
2/2
✓ Branch 0 taken 15613890 times.
✓ Branch 1 taken 31729326 times.
16115436 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5414
3/4
✓ Branch 0 taken 15502191 times.
✓ Branch 1 taken 167607 times.
✓ Branch 2 taken 15502191 times.
✗ Branch 3 not taken.
15613890 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5415
5416
2/2
✓ Branch 0 taken 1931 times.
✓ Branch 1 taken 15669798 times.
15671729 for(sprite* spr : temp_sprites)
5417
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1931 times.
1931 delete spr;
5418 79128450 }
5419
5420 // TODO: separate setting door data and drawing door
5421 28116 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5422 {
5423
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28116 times.
28116 if (type > 8) return;
5424
5425 28116 int32_t d=scr->door_combo_set;
5426
5427
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15585 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12531 times.
28116 switch(type)
5428 {
5429 case dt_wall:
5430 case dt_walk:
5431 if(!even_walls)
5432 break;
5433 [[fallthrough]];
5434 case dt_pass:
5435
3/4
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 11495 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1036 times.
12531 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5436 1036 break;
5437 [[fallthrough]];
5438 case dt_lock:
5439 case dt_shut:
5440 case dt_boss:
5441 case dt_olck:
5442 case dt_osht:
5443 case dt_obos:
5444 case dt_bomb:
5445
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7246 times.
✓ Branch 2 taken 6778 times.
✓ Branch 3 taken 6350 times.
✓ Branch 4 taken 6706 times.
27080 switch(side)
5446 {
5447 case up:
5448 7246 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5449 7246 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5450 7246 scr->sflag[pos] = 0;
5451 7246 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5452 7246 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5453 7246 scr->sflag[pos+1] = 0;
5454 7246 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5455 7246 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5456 7246 scr->sflag[pos+16] = 0;
5457 7246 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5458 7246 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5459 7246 scr->sflag[pos+16+1] = 0;
5460
5461
2/2
✓ Branch 0 taken 5428 times.
✓ Branch 1 taken 1818 times.
7246 if(redraw)
5462 {
5463 3636 putcombo(dest,(pos&15)<<4,pos&0xF0,
5464 1818 DoorComboSets[d].doorcombo_u[type][0],
5465 1818 DoorComboSets[d].doorcset_u[type][0]);
5466 3636 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5467 1818 DoorComboSets[d].doorcombo_u[type][1],
5468 1818 DoorComboSets[d].doorcset_u[type][1]);
5469 1818 }
5470
5471 7246 break;
5472
5473 case down:
5474 6778 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5475 6778 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5476 6778 scr->sflag[pos] = 0;
5477 6778 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5478 6778 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5479 6778 scr->sflag[pos+1] = 0;
5480 6778 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5481 6778 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5482 6778 scr->sflag[pos+16] = 0;
5483 6778 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5484 6778 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5485 6778 scr->sflag[pos+16+1] = 0;
5486
5487
2/2
✓ Branch 0 taken 5457 times.
✓ Branch 1 taken 1321 times.
6778 if(redraw)
5488 {
5489 2642 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5490 1321 DoorComboSets[d].doorcombo_d[type][2],
5491 1321 DoorComboSets[d].doorcset_d[type][2]);
5492 2642 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5493 1321 DoorComboSets[d].doorcombo_d[type][3],
5494 1321 DoorComboSets[d].doorcset_d[type][3]);
5495 1321 }
5496
5497 6778 break;
5498
5499 case left:
5500 6350 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5501 6350 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5502 6350 scr->sflag[pos] = 0;
5503 6350 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5504 6350 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5505 6350 scr->sflag[pos+1] = 0;
5506 6350 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5507 6350 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5508 6350 scr->sflag[pos+16] = 0;
5509 6350 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5510 6350 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5511 6350 scr->sflag[pos+16+1] = 0;
5512 6350 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5513 6350 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5514 6350 scr->sflag[pos+32] = 0;
5515 6350 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5516 6350 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5517 6350 scr->sflag[pos+32+1] = 0;
5518
5519
2/2
✓ Branch 0 taken 4867 times.
✓ Branch 1 taken 1483 times.
6350 if(redraw)
5520 {
5521 2966 putcombo(dest,(pos&15)<<4,pos&0xF0,
5522 1483 DoorComboSets[d].doorcombo_l[type][0],
5523 1483 DoorComboSets[d].doorcset_l[type][0]);
5524 2966 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5525 1483 DoorComboSets[d].doorcombo_l[type][2],
5526 1483 DoorComboSets[d].doorcset_l[type][2]);
5527 2966 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5528 1483 DoorComboSets[d].doorcombo_l[type][4],
5529 1483 DoorComboSets[d].doorcset_l[type][4]);
5530 1483 }
5531
5532 6350 break;
5533
5534 case right:
5535 6706 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5536 6706 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5537 6706 scr->sflag[pos] = 0;
5538 6706 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5539 6706 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5540 6706 scr->sflag[pos+1] = 0;
5541 6706 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5542 6706 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5543 6706 scr->sflag[pos+16] = 0;
5544 6706 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5545 6706 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5546 6706 scr->sflag[pos+16+1] = 0;
5547 6706 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5548 6706 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5549 6706 scr->sflag[pos+32] = 0;
5550 6706 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5551 6706 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5552 6706 scr->sflag[pos+32+1] = 0;
5553
5554
2/2
✓ Branch 0 taken 5053 times.
✓ Branch 1 taken 1653 times.
6706 if(redraw)
5555 {
5556 3306 putcombo(dest,(pos&15)<<4,pos&0xF0,
5557 1653 DoorComboSets[d].doorcombo_r[type][0],
5558 1653 DoorComboSets[d].doorcset_r[type][0]);
5559 3306 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5560 1653 DoorComboSets[d].doorcombo_r[type][2],
5561 1653 DoorComboSets[d].doorcset_r[type][2]);
5562 3306 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5563 1653 DoorComboSets[d].doorcombo_r[type][4],
5564 1653 DoorComboSets[d].doorcset_r[type][4]);
5565 1653 }
5566
5567 6706 break;
5568 }
5569
5570 27080 break;
5571
5572 default:
5573 break;
5574 }
5575 28116 }
5576
5577 702039 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5578 {
5579 702039 int32_t door_combo_set = scr->door_combo_set;
5580 702039 int32_t x = (pos&15)<<4;
5581 702039 int32_t y = (pos&0xF0);
5582 702039 int32_t d = door_combo_set;
5583 702039 x += offx;
5584 702039 y += offy;
5585
5586
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 160422 times.
✓ Branch 2 taken 175880 times.
✓ Branch 3 taken 196353 times.
✓ Branch 4 taken 169384 times.
702039 switch(side)
5587 {
5588 case up:
5589 320844 overcombo2(dest,x,y,
5590 160422 DoorComboSets[d].bombdoorcombo_u[0],
5591 160422 DoorComboSets[d].bombdoorcset_u[0]);
5592 320844 overcombo2(dest,x+16,y,
5593 160422 DoorComboSets[d].bombdoorcombo_u[1],
5594 160422 DoorComboSets[d].bombdoorcset_u[1]);
5595 160422 break;
5596
5597 case down:
5598 351760 overcombo2(dest,x,y,
5599 175880 DoorComboSets[d].bombdoorcombo_d[0],
5600 175880 DoorComboSets[d].bombdoorcset_d[0]);
5601 351760 overcombo2(dest,x+16,y,
5602 175880 DoorComboSets[d].bombdoorcombo_d[1],
5603 175880 DoorComboSets[d].bombdoorcset_d[1]);
5604 175880 break;
5605
5606 case left:
5607 392706 overcombo2(dest,x,y,
5608 196353 DoorComboSets[d].bombdoorcombo_l[0],
5609 196353 DoorComboSets[d].bombdoorcset_l[0]);
5610 392706 overcombo2(dest,x,y+16,
5611 196353 DoorComboSets[d].bombdoorcombo_l[1],
5612 196353 DoorComboSets[d].bombdoorcset_l[1]);
5613 392706 overcombo2(dest,x,y+16,
5614 196353 DoorComboSets[d].bombdoorcombo_l[2],
5615 196353 DoorComboSets[d].bombdoorcset_l[2]);
5616 196353 break;
5617
5618 case right:
5619 338768 overcombo2(dest,x,y,
5620 169384 DoorComboSets[d].bombdoorcombo_r[0],
5621 169384 DoorComboSets[d].bombdoorcset_r[0]);
5622 338768 overcombo2(dest,x,y+16,
5623 169384 DoorComboSets[d].bombdoorcombo_r[1],
5624 169384 DoorComboSets[d].bombdoorcset_r[1]);
5625 338768 overcombo2(dest,x,y+16,
5626 169384 DoorComboSets[d].bombdoorcombo_r[2],
5627 169384 DoorComboSets[d].bombdoorcset_r[2]);
5628 169384 break;
5629 }
5630 702039 }
5631
5632 47524 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5633 {
5634
7/8
✓ Branch 0 taken 47416 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47416 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22898 times.
✓ Branch 5 taken 24518 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22368 times.
47524 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5635 25156 return;
5636
5637 int32_t doortype;
5638
5639
10/12
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 652 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12481 times.
✓ Branch 5 taken 908 times.
✓ Branch 6 taken 1553 times.
✓ Branch 7 taken 3187 times.
✓ Branch 8 taken 1691 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 67 times.
✓ Branch 11 taken 1135 times.
22368 switch(door)
5640 {
5641 case dWALL:
5642 doortype=dt_wall;
5643 break;
5644
5645 case dWALK:
5646 doortype=dt_walk;
5647 break;
5648
5649 case dOPEN:
5650 12481 doortype=dt_pass;
5651 12481 break;
5652
5653 case dLOCKED:
5654 908 doortype=dt_lock;
5655 908 break;
5656
5657 case dUNLOCKED:
5658 1553 doortype=dt_olck;
5659 1553 break;
5660
5661 case dSHUTTER:
5662
3/4
✓ Branch 0 taken 2778 times.
✓ Branch 1 taken 409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2778 times.
3187 if(screenscrolling && ((HeroDir()^1)==side))
5663 {
5664 doortype=dt_osht;
5665 get_screen_state(scr->screen).open_doors = -4;
5666 break;
5667 }
5668
5669 [[fallthrough]];
5670 case d1WAYSHUTTER:
5671 3709 doortype=dt_shut;
5672 3709 break;
5673
5674 case dOPENSHUTTER:
5675 1691 doortype=dt_osht;
5676 1691 break;
5677
5678 case dBOSS:
5679 172 doortype=dt_boss;
5680 172 break;
5681
5682 case dOPENBOSS:
5683 67 doortype=dt_obos;
5684 67 break;
5685
5686 case dBOMBED:
5687 1135 doortype=dt_bomb;
5688 1135 break;
5689
5690 default:
5691 652 return;
5692 }
5693
5694
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5622 times.
✓ Branch 2 taken 5764 times.
✓ Branch 3 taken 5105 times.
✓ Branch 4 taken 5225 times.
21716 switch(side)
5695 {
5696 case up:
5697 5622 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5698 5622 break;
5699
5700 case down:
5701 5764 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5702 5764 break;
5703
5704 case left:
5705 5105 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5706 5105 break;
5707
5708 case right:
5709 5225 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5710 5225 break;
5711 }
5712 47524 }
5713
5714 6491 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5715 {
5716 /*
5717 #define dWALL 0 // 000 0
5718 #define dBOMB 6 // 011 0
5719 #define 8 // 100 0
5720 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5721 */
5722
5723
7/8
✓ Branch 0 taken 6491 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6487 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6404 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6396 times.
6491 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5724 91 return;
5725
5726 int32_t doortype;
5727
5728
8/12
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1527 times.
✓ Branch 8 taken 3950 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 229 times.
6400 switch(door)
5729 {
5730 case dWALL:
5731 doortype=dt_wall;
5732 break;
5733
5734 case dWALK:
5735 doortype=dt_walk;
5736 break;
5737
5738 case dOPEN:
5739 50 doortype=dt_pass;
5740 50 break;
5741
5742 case dLOCKED:
5743 doortype=dt_lock;
5744 break;
5745
5746 case dUNLOCKED:
5747 362 doortype=dt_olck;
5748 362 break;
5749
5750 case dSHUTTER:
5751
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1527 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1527 if(screenscrolling && ((HeroDir()^1)==side))
5752 {
5753 doortype=dt_osht;
5754 get_screen_state(cur_screen).open_doors = -4;
5755 break;
5756 }
5757
5758 [[fallthrough]];
5759 case d1WAYSHUTTER:
5760 1754 doortype=dt_shut;
5761 1754 break;
5762
5763 case dOPENSHUTTER:
5764 3950 doortype=dt_osht;
5765 3950 break;
5766
5767 case dBOSS:
5768 4 doortype=dt_boss;
5769 4 break;
5770
5771 case dOPENBOSS:
5772 51 doortype=dt_obos;
5773 51 break;
5774
5775 case dBOMBED:
5776 229 doortype=dt_bomb;
5777 229 break;
5778
5779 default:
5780 return;
5781 }
5782
5783
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1854 times.
✓ Branch 2 taken 1357 times.
✓ Branch 3 taken 1508 times.
✓ Branch 4 taken 1681 times.
6400 switch(side)
5784 {
5785 case up:
5786
2/2
✓ Branch 0 taken 1786 times.
✓ Branch 1 taken 68 times.
1854 switch(door)
5787 {
5788 case dBOMBED:
5789
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 68 times.
136 if(redraw)
5790 {
5791 68 over_door(scr,dest,39,side,0,0);
5792 68 }
5793 [[fallthrough]];
5794 default:
5795 1854 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5796 1854 break;
5797 }
5798
5799 1854 break;
5800
5801 case down:
5802
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 39 times.
1357 switch(door)
5803 {
5804 case dBOMBED:
5805
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5806 {
5807 39 over_door(scr,dest,135,side,0,0);
5808 39 }
5809 [[fallthrough]];
5810 default:
5811 1357 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5812 1357 break;
5813 }
5814
5815 1357 break;
5816
5817 case left:
5818
2/2
✓ Branch 0 taken 1457 times.
✓ Branch 1 taken 51 times.
1508 switch(door)
5819 {
5820 case dBOMBED:
5821
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5822 {
5823 51 over_door(scr,dest,66,side,0,0);
5824 51 }
5825 [[fallthrough]];
5826 default:
5827 1508 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5828 1508 break;
5829 }
5830
5831 1508 break;
5832
5833 case right:
5834
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 71 times.
1681 switch(door)
5835 {
5836 case dBOMBED:
5837
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71 times.
142 if(redraw)
5838 {
5839 71 over_door(scr,dest,77,side,0,0);
5840 71 }
5841 [[fallthrough]];
5842 default:
5843 1681 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5844 1681 break;
5845 }
5846
5847 1681 break;
5848 }
5849 6491 }
5850
5851 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5852 {
5853
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5854 {
5855 586 putcombo(dest,x, y, combo, cset);
5856 586 }
5857 586 }
5858
5859 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5860 {
5861
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5862 {
5863 219 overcombo(dest,x, y, combo, cset);
5864 219 }
5865 293 }
5866
5867 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5868 {
5869 125 int32_t d = scr->door_combo_set;
5870
5871
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5872 {
5873 case up:
5874 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5875 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5876 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5877 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5878 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5879 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5880 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5881 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5882 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5883 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5884 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5885 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5886 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5887 43 DoorComboSets[d].bombdoorcombo_u[0],
5888 43 DoorComboSets[d].bombdoorcset_u[0]);
5889 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5890 43 DoorComboSets[d].bombdoorcombo_u[1],
5891 43 DoorComboSets[d].bombdoorcset_u[1]);
5892 43 break;
5893
5894 case down:
5895 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5896 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5897 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5898 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5899 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5900 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5901 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5902 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5903 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5904 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5905 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5906 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5907 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5908 39 DoorComboSets[d].bombdoorcombo_d[0],
5909 39 DoorComboSets[d].bombdoorcset_d[0]);
5910 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5911 39 DoorComboSets[d].bombdoorcombo_d[1],
5912 39 DoorComboSets[d].bombdoorcset_d[1]);
5913 39 break;
5914
5915 case left:
5916 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5917 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5918 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5919 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5920 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5921 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5922 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5923 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5924 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5925 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5926 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5927 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5928 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5929 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5930 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5931 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5932 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5933 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5934 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5935 6 DoorComboSets[d].bombdoorcombo_l[0],
5936 6 DoorComboSets[d].bombdoorcset_l[0]);
5937 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5938 6 DoorComboSets[d].bombdoorcombo_l[1],
5939 6 DoorComboSets[d].bombdoorcset_l[1]);
5940 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5941 6 DoorComboSets[d].bombdoorcombo_l[2],
5942 6 DoorComboSets[d].bombdoorcset_l[2]);
5943 6 break;
5944
5945 case right:
5946 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5947 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5948 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5949 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5950 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5951 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5952 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5953 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5954 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5955 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5956 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5957 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5958 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5959 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5960 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5961 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5962 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5963 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5964 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5965 37 DoorComboSets[d].bombdoorcombo_r[0],
5966 37 DoorComboSets[d].bombdoorcset_r[0]);
5967 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5968 37 DoorComboSets[d].bombdoorcombo_r[1],
5969 37 DoorComboSets[d].bombdoorcset_r[1]);
5970 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5971 37 DoorComboSets[d].bombdoorcombo_r[2],
5972 37 DoorComboSets[d].bombdoorcset_r[2]);
5973 37 break;
5974 }
5975 125 }
5976
5977 5525477 void openshutters(mapscr* scr)
5978 {
5979 5525477 bool opened_door = false;
5980
2/2
✓ Branch 0 taken 5525477 times.
✓ Branch 1 taken 22101908 times.
27627385 for(int32_t i=0; i<4; i++)
5981
2/2
✓ Branch 0 taken 22097958 times.
✓ Branch 1 taken 3950 times.
22105858 if(scr->door[i]==dSHUTTER)
5982 {
5983 3950 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5984 3950 scr->door[i]=dOPENSHUTTER;
5985 3950 opened_door = true;
5986 3950 }
5987
5988 5525477 auto& combo_cache = combo_caches::shutter;
5989 2221785383 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
5990
3/4
✓ Branch 0 taken 2214337305 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1922594 times.
✗ Branch 3 not taken.
2216259906 if (!combo_cache.minis[handle.data()].shutter)
5991 2216259899 return;
5992
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
5993 7 return trig.trigger_flags.get(TRIGFLAG_SHUTTER);
5994 });
5995 2216259906 });
5996
5997
2/2
✓ Branch 0 taken 5522752 times.
✓ Branch 1 taken 2725 times.
5525477 if(opened_door)
5998 2725 sfx(WAV_DOOR);
5999 5525477 }
6000
6001 15698377 void clear_darkroom_bitmaps()
6002 {
6003 15698377 clear_to_color(darkscr_bmp, game->get_darkscr_color());
6004 15698377 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
6005 15698377 }
6006
6007 16725469 bool is_dark(const mapscr* scr)
6008 {
6009 16725469 bool dark = scr->flags&fDARK;
6010
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 16721747 times.
16725469 if (region_is_lit) return !dark;
6011 16721747 return dark;
6012 16725469 }
6013
6014 53163 bool scrolling_is_dark(const mapscr* scr)
6015 {
6016 53163 bool dark = scr->flags&fDARK;
6017
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 53161 times.
53163 if (scrolling_region_is_lit) return !dark;
6018 53161 return dark;
6019 53163 }
6020
6021 38407 bool is_any_dark()
6022 {
6023 38407 bool dark = false;
6024 78070 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
6025 39663 dark |= (bool)(is_dark(scr));
6026 39663 });
6027 38407 return dark;
6028 }
6029
6030
3/4
✓ Branch 0 taken 3003 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2574 times.
✓ Branch 3 taken 429 times.
3003 static mapscr prev_origin_scrs[7];
6031 429 static std::set<int> loadscr_ffc_script_ids_to_remove;
6032
6033 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
6034 {
6035 mapscr* base_scr = screens[0];
6036 mapscr* previous_scr = &prev_origin_scrs[0];
6037
6038 for (int i = 0; i < 176; i++)
6039 {
6040 if (base_scr->data[i] == 0)
6041 {
6042 base_scr->data[i] = previous_scr->data[i];
6043 base_scr->sflag[i] = previous_scr->sflag[i];
6044 base_scr->cset[i] = previous_scr->cset[i];
6045 }
6046 }
6047
6048 for (int i = 0; i < 6; i++)
6049 {
6050 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
6051 {
6052 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
6053 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
6054
6055 for (int j = 0; j < 176; j++)
6056 {
6057 if (TheMaps[lm].data[j] == 0)
6058 {
6059 TheMaps[lm].data[j] = TheMaps[fm].data[j];
6060 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
6061 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
6062 }
6063 }
6064 }
6065 }
6066
6067 for (int i = 1; i <= 6; i++)
6068 {
6069 mapscr* scr = screens[i];
6070 previous_scr = &prev_origin_scrs[i];
6071
6072 if (scr->layermap[i] > 0)
6073 {
6074 for (int y = 0; y < 11; y++)
6075 {
6076 for (int x = 0; x < 16; x++)
6077 {
6078 int c = y*16+x;
6079
6080 if (scr->data[c]==0)
6081 {
6082 scr->data[c] = previous_scr->data[c];
6083 scr->sflag[c] = previous_scr->sflag[c];
6084 scr->cset[c] = previous_scr->cset[c];
6085 }
6086 }
6087 }
6088 }
6089 }
6090 }
6091
6092 38747 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
6093 {
6094 38747 std::vector<mapscr*> screens;
6095
6096
1/2
✓ Branch 0 taken 38747 times.
✗ Branch 1 not taken.
38747 const mapscr* source = get_canonical_scr(cur_map, screen);
6097
2/4
✓ Branch 0 taken 38747 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38747 times.
✗ Branch 3 not taken.
38747 mapscr* base_scr = new mapscr(*source);
6098 38747 temporary_screens[screen*7] = base_scr;
6099
1/2
✓ Branch 0 taken 38747 times.
✗ Branch 1 not taken.
38747 screens.push_back(base_scr);
6100
6101 38747 base_scr->valid |= mVALID; // layer 0 is always valid
6102
6103
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 37503 times.
38747 if (screen == cur_screen)
6104 37503 origin_scr = base_scr;
6105
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 37503 times.
38747 if (screen == Hero.current_screen)
6106 37503 hero_scr = prev_hero_scr = base_scr;
6107
6108
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 38603 times.
38747 if (source->script > 0)
6109
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6110
6111
2/2
✓ Branch 0 taken 38747 times.
✓ Branch 1 taken 232482 times.
271229 for (int i = 0; i < 6; i++)
6112 {
6113
2/2
✓ Branch 0 taken 176005 times.
✓ Branch 1 taken 56477 times.
232482 if(source->layermap[i]>0)
6114 {
6115
3/6
✓ Branch 0 taken 56477 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56477 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 56477 times.
✗ Branch 5 not taken.
56477 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
6116 56477 layer_scr->map = cur_map;
6117 56477 layer_scr->screen = screen;
6118 56477 layer_scr->valid |= mVALID;
6119
1/2
✓ Branch 0 taken 56477 times.
✗ Branch 1 not taken.
56477 screens.push_back(layer_scr);
6120 56477 }
6121 else
6122 {
6123
2/4
✓ Branch 0 taken 176005 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 176005 times.
✗ Branch 3 not taken.
176005 mapscr* layer_scr = new mapscr();
6124 176005 layer_scr->map = cur_map;
6125 176005 layer_scr->screen = screen;
6126
1/2
✓ Branch 0 taken 176005 times.
✗ Branch 1 not taken.
176005 screens.push_back(layer_scr);
6127 }
6128 232482 temporary_screens[screen*7+i+1] = screens[i+1];
6129 232482 }
6130
6131
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38747 times.
38747 if (screen_overlay)
6132 handle_screen_overlay(screens);
6133
6134
2/2
✓ Branch 0 taken 145 times.
✓ Branch 1 taken 38602 times.
38747 if (ffc_overlay)
6135 {
6136 145 mapscr* previous_scr = &prev_origin_scrs[0];
6137
1/2
✓ Branch 0 taken 145 times.
✗ Branch 1 not taken.
145 int num_ffcs = previous_scr->numFFC();
6138
2/2
✓ Branch 0 taken 4640 times.
✓ Branch 1 taken 145 times.
4785 for (int i = 0; i < num_ffcs; i++)
6139 {
6140
2/2
✓ Branch 0 taken 4365 times.
✓ Branch 1 taken 275 times.
4640 if ((previous_scr->ffcs[i].flags&ffc_carryover))
6141 {
6142
2/4
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 275 times.
✗ Branch 3 not taken.
275 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
6143 275 ffc.screen_spawned = screen;
6144
6145
1/2
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
275 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
6146
1/2
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
275 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
6147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 275 times.
275 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
6148 {
6149 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
6150 }
6151 275 }
6152 4640 }
6153 145 }
6154
6155
1/2
✓ Branch 0 taken 38747 times.
✗ Branch 1 not taken.
2250345 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6156
1/2
✓ Branch 0 taken 38747 times.
✗ Branch 1 not taken.
38747 int num_ffcs = base_scr->numFFC();
6157
2/2
✓ Branch 0 taken 1105799 times.
✓ Branch 1 taken 38747 times.
1144546 for (word i = 0; i < num_ffcs; i++)
6158 {
6159 1105799 base_scr->ffcs[i].screen_spawned = screen;
6160 1105799 base_scr->ffcs[i].x += offx;
6161 1105799 base_scr->ffcs[i].y += offy;
6162 1105799 }
6163 38747 }
6164
6165 38747 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
6166 {
6167 38747 mapscr* base_scr = get_scr(screen);
6168 38747 int mi = mapind(cur_map, screen);
6169
6170 // Apply perm secrets, if applicable.
6171
2/2
✓ Branch 0 taken 11509 times.
✓ Branch 1 taken 27238 times.
38747 if (canPermSecret(dmap, screen))
6172 {
6173
2/2
✓ Branch 0 taken 24334 times.
✓ Branch 1 taken 2904 times.
27238 if(game->maps[mi] & mSECRET) // if special stuff done before
6174 {
6175 2904 reveal_hidden_stairs(base_scr, screen, false);
6176 2904 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
6177 2904 }
6178
2/2
✓ Branch 0 taken 27235 times.
✓ Branch 1 taken 3 times.
27238 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
6179 {
6180
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
6181 {
6182 21 mapscr* layer_scr = get_scr_layer(screen, layer);
6183
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
6184 {
6185 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
6186
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
6187 {
6188
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
6189 {
6190 3 layer_scr->data[pos] += 1;
6191 3 }
6192 3 }
6193 3696 }
6194 21 }
6195 3 }
6196 27238 }
6197
6198 38747 auto screen_handles = create_screen_handles(base_scr);
6199
6200 38747 int destlvl = DMaps[dmap].level;
6201 38747 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6202 38747 toggle_gswitches_load(screen_handles);
6203
6204 38747 bool should_check_for_state_things = (screen < 0x80);
6205
2/2
✓ Branch 0 taken 906 times.
✓ Branch 1 taken 37841 times.
38747 if (should_check_for_state_things)
6206 {
6207
2/2
✓ Branch 0 taken 37407 times.
✓ Branch 1 taken 434 times.
37841 if (game->maps[mi]&mLOCKBLOCK)
6208 434 remove_lockblocks(screen_handles);
6209
2/2
✓ Branch 0 taken 37752 times.
✓ Branch 1 taken 89 times.
37841 if (game->maps[mi]&mBOSSLOCKBLOCK)
6210 89 remove_bosslockblocks(screen_handles);
6211
2/2
✓ Branch 0 taken 37673 times.
✓ Branch 1 taken 168 times.
37841 if (game->maps[mi]&mCHEST)
6212 168 remove_chests(screen_handles);
6213
1/2
✓ Branch 0 taken 37841 times.
✗ Branch 1 not taken.
37841 if (game->maps[mi]&mLOCKEDCHEST)
6214 remove_lockedchests(screen_handles);
6215
2/2
✓ Branch 0 taken 37830 times.
✓ Branch 1 taken 11 times.
37841 if (game->maps[mi]&mBOSSCHEST)
6216 11 remove_bosschests(screen_handles);
6217
6218 37841 clear_xdoors_mi(screen_handles, mi, true);
6219 37841 clear_xstatecombos_mi(screen_handles, mi, true);
6220 37841 }
6221
6222 // check doors
6223
2/2
✓ Branch 0 taken 27237 times.
✓ Branch 1 taken 11510 times.
38747 if (isdungeon(dmap, screen))
6224 {
6225
2/2
✓ Branch 0 taken 46040 times.
✓ Branch 1 taken 11510 times.
57550 for(int32_t i=0; i<4; i++)
6226 {
6227 46040 int32_t door=base_scr->door[i];
6228
6229
5/5
✓ Branch 0 taken 5295 times.
✓ Branch 1 taken 36447 times.
✓ Branch 2 taken 2370 times.
✓ Branch 3 taken 230 times.
✓ Branch 4 taken 1698 times.
46040 switch(door)
6230 {
6231 case d1WAYSHUTTER:
6232 case dSHUTTER:
6233
3/4
✓ Branch 0 taken 1691 times.
✓ Branch 1 taken 3604 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1691 times.
5295 if ((ldir^1)==i && screen == Hero.current_screen)
6234 {
6235 1691 base_scr->door[i]=dOPENSHUTTER;
6236 1691 }
6237
6238 5295 get_screen_state(screen).open_doors = -4;
6239 5295 break;
6240
6241 case dLOCKED:
6242
3/4
✓ Branch 0 taken 2370 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 897 times.
2370 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6243 {
6244 1473 base_scr->door[i]=dUNLOCKED;
6245 1473 }
6246
6247 2370 break;
6248
6249 case dBOSS:
6250
3/4
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 168 times.
230 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6251 {
6252 62 base_scr->door[i]=dOPENBOSS;
6253 62 }
6254
6255 230 break;
6256
6257 case dBOMB:
6258
3/4
✓ Branch 0 taken 1698 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1084 times.
✓ Branch 3 taken 614 times.
1698 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6259 {
6260 1084 base_scr->door[i]=dBOMBED;
6261 1084 }
6262
6263 1698 break;
6264 }
6265
6266 46040 update_door(base_scr, i, base_scr->door[i]);
6267
6268
4/4
✓ Branch 0 taken 41481 times.
✓ Branch 1 taken 4559 times.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 40745 times.
46040 if(door==dSHUTTER||door==d1WAYSHUTTER)
6269 {
6270 5295 base_scr->door[i]=door;
6271 5295 }
6272 46040 }
6273 11510 }
6274
6275
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 38608 times.
38747 if (!(base_scr->flags3 & fCYCLEONINIT))
6276 38608 return;
6277
6278
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 973 times.
1112 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6279 {
6280
4/4
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 139 times.
✓ Branch 2 taken 383 times.
✓ Branch 3 taken 451 times.
973 if (j<0 || base_scr->layermap[j] > 0)
6281 {
6282 522 mapscr* layer_scr = get_scr_layer(screen, j + 1);
6283
3/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 139 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 383 times.
522 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
6284 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
6285
6286
2/2
✓ Branch 0 taken 91872 times.
✓ Branch 1 taken 522 times.
92394 for(int32_t i=0; i<176; ++i)
6287 {
6288 91872 int32_t c=layerscreen->data[i];
6289
6290 // New screen flag: Cycle Combos At Screen Init
6291
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 91807 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
91872 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6292 {
6293 65 int32_t r = 0;
6294
6295
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
6296 {
6297 84 newcombo const& cmb = combobuf[c];
6298 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6300 84 layerscreen->data[i] = cid;
6301
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6303 84 c = layerscreen->data[i];
6304 }
6305 65 }
6306 91872 }
6307 522 }
6308 973 }
6309 38747 }
6310
6311 // Set `cur_screen` to `screen` and load new screens into temporary memory.
6312 //
6313 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
6314 // the game, etc...)
6315 //
6316 // Note: for regions, only the initial screen load calls this function. Simply walking between
6317 // screens in the same region does not use this, because every screen in a region is loaded into
6318 // temporary memory up front.
6319 //
6320 // If scr >= 0x80, `Hero.current_screen` will be saved to `home_screen` and also be loaded into
6321 // `special_warp_return_scr`.
6322 //
6323 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
6324 // on all layers (but only where the new screen has a 0 combo).
6325 //
6326 // TODO: loadscr should set curdmap, but currently callers do that.
6327 37503 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6328 {
6329 37503 zapp_reporting_set_tag("screen", screen);
6330
2/2
✓ Branch 0 taken 9309 times.
✓ Branch 1 taken 28194 times.
37503 if (destdmap != -1)
6331 9309 zapp_reporting_set_tag("dmap", destdmap);
6332
6333 37503 int32_t orig_destdmap = destdmap;
6334
2/2
✓ Branch 0 taken 9309 times.
✓ Branch 1 taken 28194 times.
37503 if (destdmap < 0) destdmap = cur_dmap;
6335
6336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37503 times.
37503 if (replay_is_active())
6337 {
6338
2/2
✓ Branch 0 taken 28194 times.
✓ Branch 1 taken 9309 times.
37503 if (orig_destdmap != -1)
6339 {
6340
2/2
✓ Branch 0 taken 8238 times.
✓ Branch 1 taken 1071 times.
9309 if (strlen(DMaps[orig_destdmap].name) > 0)
6341 {
6342
1/2
✓ Branch 0 taken 8238 times.
✗ Branch 1 not taken.
8238 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6343 8238 }
6344 else
6345 {
6346
1/2
✓ Branch 0 taken 1071 times.
✗ Branch 1 not taken.
1071 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6347 }
6348 9309 }
6349 37503 replay_step_comment_loadscr(screen);
6350
6351 // Reset the rngs and frame count so that recording steps can be modified without impacting
6352 // behavior of later screens.
6353 37503 replay_sync_rng();
6354 37503 }
6355
6356
2/2
✓ Branch 0 taken 1753743 times.
✓ Branch 1 taken 37503 times.
1791246 for (auto& state : get_screen_states())
6357 1753743 state.second.triggered_secrets = false;
6358 37503 slopes.clear();
6359 37503 Hero.clear_platform_ffc();
6360 37503 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6361 37503 clear_darkroom_bitmaps();
6362 37503 msgscr = nullptr;
6363
6364
2/2
✓ Branch 0 taken 52509058 times.
✓ Branch 1 taken 37503 times.
52546561 for (word x=0; x<animated_combos; x++)
6365 {
6366
2/2
✓ Branch 0 taken 21102474 times.
✓ Branch 1 taken 31406584 times.
52509058 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6367 {
6368 21102474 combobuf[animated_combo_table4[x][0]].aclk = 0;
6369 21102474 }
6370 52509058 }
6371 37503 reset_combo_animations2();
6372 37503 region_is_lit = false;
6373
6374 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6375 // of the new ones.
6376 37503 bool origin_ffc_overlay = false;
6377
2/2
✓ Branch 0 taken 1172 times.
✓ Branch 1 taken 36331 times.
37503 if (origin_scr)
6378 {
6379
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 36329 times.
36331 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6380 {
6381 36329 int c = origin_scr->numFFC();
6382
2/2
✓ Branch 0 taken 36184 times.
✓ Branch 1 taken 1039713 times.
1075897 for (int i = 0; i < c; i++)
6383 {
6384
2/2
✓ Branch 0 taken 1039568 times.
✓ Branch 1 taken 145 times.
1039713 if (origin_scr->ffcs[i].flags&ffc_carryover)
6385 {
6386 145 origin_ffc_overlay = true;
6387 145 break;
6388 }
6389 1039568 }
6390 36329 }
6391
6392
3/4
✓ Branch 0 taken 36331 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 145 times.
✓ Branch 3 taken 36186 times.
36331 if (origin_screen_overlay || origin_ffc_overlay)
6393 {
6394
2/2
✓ Branch 0 taken 1015 times.
✓ Branch 1 taken 145 times.
1160 for (int i = 0; i <= 6; i++)
6395 {
6396 1015 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6397
1/2
✓ Branch 0 taken 1015 times.
✗ Branch 1 not taken.
1015 if (prev_scr)
6398 1015 prev_origin_scrs[i] = *prev_scr;
6399 else
6400 prev_origin_scrs[i] = {};
6401 1015 }
6402 145 }
6403 36331 }
6404
6405 // When loading a new screen, all previous FFC scripts end, with one exception.
6406 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6407 // them, but scripts that need their data to persist will be removed.
6408 37503 loadscr_ffc_script_ids_to_remove.clear();
6409
2/2
✓ Branch 0 taken 83158837 times.
✓ Branch 1 taken 37503 times.
83196340 for (auto& key : scriptEngineDatas | std::views::keys)
6410 {
6411
2/2
✓ Branch 0 taken 82028844 times.
✓ Branch 1 taken 1129993 times.
83158837 if (key.first == ScriptType::FFC)
6412 1129993 loadscr_ffc_script_ids_to_remove.insert(key.second);
6413 }
6414
6415 37503 load_region(destdmap, screen);
6416
2/2
✓ Branch 0 taken 906 times.
✓ Branch 1 taken 36597 times.
37503 home_screen = screen >= 0x80 ? Hero.current_screen : cur_screen;
6417 37503 Hero.current_screen = screen;
6418
6419 37503 cpos_clear_all();
6420 37503 FFCore.destroyScriptableObjectsOfType(ScriptType::Screen);
6421 37503 FFCore.clear_combo_scripts();
6422
6423
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 37339 times.
37503 if (is_in_scrolling_region())
6424 {
6425
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6426 {
6427
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6428 {
6429
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6430
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6431 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6432 1408 }
6433 20992 }
6434 164 }
6435 else
6436 {
6437 37339 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6438 }
6439
6440 37503 prepare_current_region_handles();
6441
6442
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 37339 times.
37503 if (is_in_scrolling_region())
6443 {
6444
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6445 {
6446
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6447 {
6448 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6449 1408 }
6450 20992 }
6451 164 }
6452 else
6453 {
6454 37339 load_a_screen_and_layers_post(destdmap, screen, ldir);
6455 }
6456
6457 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6458
2/2
✓ Branch 0 taken 36597 times.
✓ Branch 1 taken 906 times.
37503 if (screen >= 0x80)
6459
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 430 times.
906 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6460
6461 37503 update_slope_comboposes();
6462 37503 cpos_force_update();
6463 37503 trig_trigger_groups();
6464
6465
2/2
✓ Branch 0 taken 1129718 times.
✓ Branch 1 taken 37503 times.
1167221 for (int index : loadscr_ffc_script_ids_to_remove)
6466 {
6467 // Note: ideally would use "destroySprite", but during scrolling the previous
6468 // screen's FFCs are still accessible (even though only the new screen's FFC scripts run).
6469 // The only difference is a call to "release_sprite_owned_objects". To defer FFC script
6470 // owned objects being released until the end of the scroll, here "destroyScriptableObject"
6471 // is used instead.
6472 //
6473 // So when is "release_sprite_owned_objects" called for FFCs? For scrolling screen
6474 // transitions, it's at the end of "scrollscr" via "delete_temporary_screens". Otherwise,
6475 // it is called above when "load_region" calls "clear_temporary_screens".
6476 1129718 FFCore.destroyScriptableObject(ScriptType::FFC, index);
6477 }
6478
6479 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6480 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6481 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6482 // It is up to the quest designer to make their subscreen be actually transparent.
6483 //
6484 // When not in "extended height mode" (otherwise 56 is 0):
6485 // - playing_field_offset: 56, but changes during earthquakes
6486 // - original_playing_field_offset: always 56
6487 //
6488 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6489 // - yofs of sprites
6490 // - bitmap y offsets in draw_screen
6491 // - drawing offsets for putscr, do_layer
6492 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6493 // - lots more
6494 //
6495 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6496
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 37361 times.
37503 if (is_extended_height_mode())
6497 {
6498 142 playing_field_offset = 0;
6499 142 original_playing_field_offset = 0;
6500 // A few sprites exist as globals, so we must manually reset them.
6501 142 Hero.yofs = 0;
6502 142 mblock2.yofs = 0;
6503 142 }
6504 else
6505 {
6506 37361 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6507 37361 original_playing_field_offset = 56;
6508 }
6509 37503 is_any_room_dark = is_any_dark();
6510
6511 37503 game->load_portal();
6512 37503 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6513
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 37468 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
37503 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6514 {
6515 delete Hero.lift_wpn;
6516 Hero.lift_wpn = nullptr;
6517 }
6518
6519 37503 enemy_spawning_has_checked_been_here = false;
6520 37503 markBmap(-1, Hero.current_screen);
6521 37503 Hero.maybe_begin_advanced_maze();
6522 37503 }
6523
6524 // Don't use this directly! Use `loadscr` instead.
6525 906 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6526 {
6527
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
906 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6528
6529 906 mapscr previous_scr = *special_warp_return_scr;
6530 906 mapscr* scr = special_warp_return_scr;
6531
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
906 const mapscr* source = get_canonical_scr(cur_map, screen);
6532
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
906 *scr = *source;
6533
6534
2/2
✓ Branch 0 taken 5436 times.
✓ Branch 1 taken 906 times.
6342 for (int i = 1; i <= 6; i++)
6535 {
6536
2/2
✓ Branch 0 taken 5053 times.
✓ Branch 1 taken 383 times.
5436 if (scr->layermap[i-1] > 0)
6537
2/4
✓ Branch 0 taken 383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
383 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6538 else
6539
2/4
✓ Branch 0 taken 5053 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5053 times.
✗ Branch 3 not taken.
5053 special_warp_return_scrs[i] = {};
6540 5436 }
6541
6542 906 scr->valid |= mVALID; //layer 0 is always valid
6543
6544
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 906 times.
906 if ( source->script > 0 )
6545 {
6546 scr->script = source->script;
6547 for ( int32_t q = 0; q < 8; q++ )
6548 {
6549 scr->screeninitd[q] = source->screeninitd[q];
6550 }
6551 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6552 }
6553 else
6554 {
6555 906 scr->script = 0;
6556 }
6557
6558
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
906 if(overlay)
6559 {
6560 for(int32_t c=0; c< 176; ++c)
6561 {
6562 if(scr->data[c]==0)
6563 {
6564 scr->data[c]=previous_scr.data[c];
6565 scr->sflag[c]=previous_scr.sflag[c];
6566 scr->cset[c]=previous_scr.cset[c];
6567 }
6568 }
6569
6570 for(int32_t i=0; i<6; i++)
6571 {
6572 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6573 {
6574 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6575 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6576
6577 for(int32_t c=0; c< 176; ++c)
6578 {
6579 if(TheMaps[lm].data[c]==0)
6580 {
6581 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6582 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6583 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6584 }
6585 }
6586 }
6587 }
6588 }
6589
6590
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
29867 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6591
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
906 int c = scr->numFFC();
6592
2/2
✓ Branch 0 taken 906 times.
✓ Branch 1 taken 28961 times.
29867 for (word i = 0; i < c; i++)
6593 {
6594 28961 scr->ffcs[i].screen_spawned = screen;
6595
1/2
✓ Branch 0 taken 28961 times.
✗ Branch 1 not taken.
28961 scr->ffcs[i].x += offx;
6596
1/2
✓ Branch 0 taken 28961 times.
✗ Branch 1 not taken.
28961 scr->ffcs[i].y += offy;
6597 28961 }
6598
6599 906 int mi = mapind(cur_map, screen);
6600
6601 // Apply perm secrets, if applicable.
6602
3/4
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 535 times.
✓ Branch 3 taken 371 times.
906 if(canPermSecret(destdmap,screen))
6603 {
6604
3/4
✓ Branch 0 taken 535 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 203 times.
✓ Branch 3 taken 332 times.
535 if(game->maps[mi]&mSECRET) // if special stuff done before
6605 {
6606
1/2
✓ Branch 0 taken 203 times.
✗ Branch 1 not taken.
203 reveal_hidden_stairs(scr, screen, false);
6607
6608
1/2
✓ Branch 0 taken 203 times.
✗ Branch 1 not taken.
203 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6609
1/2
✓ Branch 0 taken 203 times.
✗ Branch 1 not taken.
203 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6610 203 bool do_replay_comment = true;
6611 203 bool from_active_screen = false;
6612
2/4
✓ Branch 0 taken 203 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 203 times.
✗ Branch 3 not taken.
203 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6613 203 }
6614
2/4
✓ Branch 0 taken 535 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 535 times.
✗ Branch 3 not taken.
535 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6615 {
6616 for (int layer = 0; layer <= 6; layer++)
6617 {
6618 mapscr* tscr = &special_warp_return_scrs[layer];
6619 for (int pos = 0; pos < 176; pos++)
6620 {
6621 newcombo const* cmb = &combobuf[tscr->data[pos]];
6622 if(cmb->type == cLIGHTTARGET)
6623 {
6624 if(!(cmb->usrflags&cflag1)) //Unlit version
6625 {
6626 tscr->data[pos] += 1;
6627 }
6628 }
6629 }
6630 }
6631 }
6632 535 }
6633
6634 screen_handles_t screen_handles;
6635
2/2
✓ Branch 0 taken 906 times.
✓ Branch 1 taken 6342 times.
7248 for (int i = 0; i <= 6; i++)
6636
3/4
✓ Branch 0 taken 6342 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1283 times.
✓ Branch 3 taken 5059 times.
6342 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6637
6638
2/4
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 906 times.
✗ Branch 3 not taken.
906 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6639
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
906 toggle_gswitches_load(screen_handles);
6640
6641
3/4
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 901 times.
906 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6642 {
6643
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6644 5 }
6645
6646
3/4
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 905 times.
906 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6647 {
6648
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6649 1 }
6650
6651
2/4
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 906 times.
906 if(game->maps[mi]&mCHEST) // if special stuff done before
6652 {
6653 remove_chests(screen_handles);
6654 }
6655
6656
2/4
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 906 times.
906 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6657 {
6658 remove_lockedchests(screen_handles);
6659 }
6660
6661
2/4
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 906 times.
906 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6662 {
6663 remove_bosschests(screen_handles);
6664 }
6665
6666
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
906 clear_xdoors(screen_handles, true);
6667
1/2
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
906 clear_xstatecombos(screen_handles, true);
6668
6669 // check doors
6670
3/4
✓ Branch 0 taken 906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 535 times.
✓ Branch 3 taken 371 times.
906 if (isdungeon(destdmap, screen))
6671 {
6672
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 371 times.
1855 for(int32_t i=0; i<4; i++)
6673 {
6674 1484 int32_t door=scr->door[i];
6675
6676
4/5
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1295 times.
1484 switch(door)
6677 {
6678 case d1WAYSHUTTER:
6679 case dSHUTTER:
6680 if ((ldir^1)==i && screen == home_screen)
6681 {
6682 scr->door[i]=dOPENSHUTTER;
6683 }
6684
6685 get_screen_state(screen).open_doors = -4;
6686 105 break;
6687
6688 case dLOCKED:
6689
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 80 times.
91 if(game->maps[mi]&(mDOOR_UP<<i))
6690 {
6691 80 scr->door[i]=dUNLOCKED;
6692 80 }
6693
6694 91 break;
6695
6696 case dBOSS:
6697
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5 times.
9 if(game->maps[mi]&(mDOOR_UP<<i))
6698 {
6699 5 scr->door[i]=dOPENBOSS;
6700 5 }
6701
6702 9 break;
6703
6704 case dBOMB:
6705
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 51 times.
89 if(game->maps[mi]&(mDOOR_UP<<i))
6706 {
6707 51 scr->door[i]=dBOMBED;
6708 51 }
6709
6710 89 break;
6711 }
6712
6713
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 105 times.
1589 update_door(scr, i, scr->door[i]);
6714
6715
4/4
✓ Branch 0 taken 1390 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1379 times.
1484 if(door==dSHUTTER||door==d1WAYSHUTTER)
6716 {
6717 105 scr->door[i]=door;
6718 105 }
6719 1484 }
6720 371 }
6721
6722
2/2
✓ Branch 0 taken 6132 times.
✓ Branch 1 taken 1116 times.
7248 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6723 {
6724
4/4
✓ Branch 0 taken 5436 times.
✓ Branch 1 taken 696 times.
✓ Branch 2 taken 593 times.
✓ Branch 3 taken 4843 times.
6132 if (j<0 || scr->layermap[j] > 0)
6725 {
6726
4/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 906 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1 times.
1289 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6727 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6728
6729
2/2
✓ Branch 0 taken 226654 times.
✓ Branch 1 taken 1499 times.
228153 for(int32_t i=0; i<176; ++i)
6730 {
6731 226654 int32_t c=layerscreen->data[i];
6732
6733 // New screen flag: Cycle Combos At Screen Init
6734
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 226648 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 210 times.
✓ Branch 7 taken 210 times.
226654 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6735 {
6736 210 int32_t r = 0;
6737
6738
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 210 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
210 while(combobuf[c].can_cycle() && r++ < 10)
6739 {
6740 newcombo const& cmb = combobuf[c];
6741 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6742 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6743 layerscreen->data[i] = cid;
6744 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6745 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6746 c = layerscreen->data[i];
6747 }
6748 }
6749 226864 }
6750 1499 }
6751 6342 }
6752 1536 }
6753
6754 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6755 // instead returns an array of mapscr.
6756 // Used to draw/save the map.
6757 47360 std::array<mapscr, 7> loadscr2(int32_t screen)
6758 {
6759 47360 std::array<mapscr, 7> scrs;
6760 47360 mapscr* scr = &scrs[0];
6761
6762
2/2
✓ Branch 0 taken 66834661 times.
✓ Branch 1 taken 47360 times.
66882021 for(word x=0; x<animated_combos; x++)
6763 {
6764
2/2
✓ Branch 0 taken 33899045 times.
✓ Branch 1 taken 32935616 times.
66834661 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6765 {
6766 32935616 combobuf[animated_combo_table4[x][0]].aclk=0;
6767 32935616 }
6768 66834661 }
6769
6770
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 const mapscr* source = get_canonical_scr(cur_map, screen);
6771
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if (!source->is_valid())
6772 {
6773 scrs[0].valid = 0;
6774 return scrs;
6775 }
6776
6777
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 *scr = *get_canonical_scr(cur_map, screen);
6778
2/2
✓ Branch 0 taken 284160 times.
✓ Branch 1 taken 47360 times.
331520 for (int i = 1; i <= 6; i++)
6779 {
6780
2/2
✓ Branch 0 taken 209501 times.
✓ Branch 1 taken 74659 times.
284160 if (scr->layermap[i-1] > 0)
6781
2/4
✓ Branch 0 taken 74659 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 74659 times.
✗ Branch 3 not taken.
74659 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6782 else
6783
2/4
✓ Branch 0 taken 209501 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 209501 times.
✗ Branch 3 not taken.
209501 scrs[i] = {};
6784 284160 }
6785
6786 screen_handles_t screen_handles;
6787
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 331520 times.
378880 for (int i = 0; i < 7; i++)
6788
3/4
✓ Branch 0 taken 331520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114582 times.
✓ Branch 3 taken 216938 times.
331520 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6789
6790 47360 int mi = mapind(cur_map, screen);
6791
6792
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47306 times.
✓ Branch 3 taken 54 times.
47360 if(canPermSecret(-1,screen))
6793 {
6794
3/4
✓ Branch 0 taken 47306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6344 times.
✓ Branch 3 taken 40962 times.
47306 if(game->maps[mi]&mSECRET) // if special stuff done before
6795 {
6796
1/2
✓ Branch 0 taken 6344 times.
✗ Branch 1 not taken.
6344 reveal_hidden_stairs(scr, screen, false);
6797 6344 bool from_active_screen = false;
6798 6344 bool do_replay_comment = true;
6799
1/2
✓ Branch 0 taken 6344 times.
✗ Branch 1 not taken.
6344 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6800 6344 }
6801
3/4
✓ Branch 0 taken 47306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47289 times.
✓ Branch 3 taken 17 times.
47306 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6802 {
6803
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6804 {
6805 119 mapscr* tscr = &scrs[layer];
6806
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6807 {
6808 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6809
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6810 {
6811
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6812 {
6813 17 tscr->data[pos] += 1;
6814 17 }
6815 17 }
6816 20944 }
6817 119 }
6818 17 }
6819 47306 }
6820
6821
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 271 times.
✓ Branch 3 taken 47089 times.
47360 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6822 {
6823
1/2
✓ Branch 0 taken 271 times.
✗ Branch 1 not taken.
271 remove_lockblocks(screen_handles);
6824 271 }
6825
6826
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 47359 times.
47360 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6827 {
6828
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6829 1 }
6830
6831
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106 times.
✓ Branch 3 taken 47254 times.
47360 if(game->maps[mi]&mCHEST) // if special stuff done before
6832 {
6833
1/2
✓ Branch 0 taken 106 times.
✗ Branch 1 not taken.
106 remove_chests(screen_handles);
6834 106 }
6835
6836
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 47336 times.
47360 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6837 {
6838
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6839 24 }
6840
6841
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 47360 times.
47360 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6842 {
6843 remove_bosschests(screen_handles);
6844 }
6845
6846
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 clear_xdoors(screen_handles);
6847
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 clear_xstatecombos(screen_handles);
6848
6849 // check doors
6850
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47306 times.
✓ Branch 3 taken 54 times.
47360 if (isdungeon(screen))
6851 {
6852
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6853 {
6854 216 int32_t door=scr->door[i];
6855 216 bool putit=true;
6856
6857
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6858 {
6859 case d1WAYSHUTTER:
6860 case dSHUTTER:
6861 61 break;
6862
6863 case dLOCKED:
6864
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(mDOOR_UP<<i))
6865 {
6866 12 scr->door[i]=dUNLOCKED;
6867 12 }
6868
6869 12 break;
6870
6871 case dBOSS:
6872
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(mDOOR_UP<<i))
6873 {
6874 scr->door[i]=dOPENBOSS;
6875 }
6876
6877 4 break;
6878
6879 case dBOMB:
6880 if(game->maps[mi]&(mDOOR_UP<<i))
6881 {
6882 scr->door[i]=dBOMBED;
6883 }
6884
6885 break;
6886 }
6887
6888
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6889 {
6890
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6891 216 }
6892
6893
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6894 {
6895 61 scr->door[i]=door;
6896 61 }
6897 216 }
6898 54 }
6899
6900
2/2
✓ Branch 0 taken 331520 times.
✓ Branch 1 taken 47360 times.
378880 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6901 {
6902
4/4
✓ Branch 0 taken 284160 times.
✓ Branch 1 taken 47360 times.
✓ Branch 2 taken 74659 times.
✓ Branch 3 taken 209501 times.
331520 if (j < 0 || scr->layermap[j] > 0)
6903 {
6904
2/2
✓ Branch 0 taken 74659 times.
✓ Branch 1 taken 47360 times.
122019 mapscr *layerscreen= (j<0 ? scr
6905 74659 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6906
6907
2/2
✓ Branch 0 taken 21475344 times.
✓ Branch 1 taken 122019 times.
21597363 for(int32_t i=0; i<176; ++i)
6908 {
6909 21475344 int32_t c=layerscreen->data[i];
6910
6911 // New screen flag: Cycle Combos At Screen Init
6912
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 21475344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
21475344 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6913 {
6914 int32_t r = 0;
6915
6916 while(combobuf[c].can_cycle() && r++ < 10)
6917 {
6918 newcombo const& cmb = combobuf[c];
6919 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6920 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6921 layerscreen->data[i] = cid;
6922 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6923 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6924 c = layerscreen->data[i];
6925 }
6926 }
6927 21475344 }
6928 122019 }
6929 331520 }
6930
6931 47360 return scrs;
6932
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 }
6933
6934 19745235 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6935 {
6936 // This is a bogus value while screenscrolling == true, but that's ok
6937 // because it is only used to calculate the rpos, and during screenscrolling
6938 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6939 // is always the same no matter the value of scr.
6940 19745235 int screen = get_screen_for_world_xy(x, y);
6941
6942 19745235 x -= viewport.x;
6943 19745235 y -= viewport.y;
6944
6945
3/6
✓ Branch 0 taken 19745235 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19745235 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19745235 times.
19745235 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6946 {
6947 rectfill(dest,x,y,x+255,y+175,0);
6948 return;
6949 }
6950
6951 39343003 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6952
2/2
✓ Branch 0 taken 19597768 times.
✓ Branch 1 taken 147467 times.
19745235 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
6953
2/2
✓ Branch 0 taken 243651 times.
✓ Branch 1 taken 19354117 times.
19597768 || !get_qr(qr_CLASSIC_DRAWING_ORDER);
6954
6955 int start_x, end_x, start_y, end_y;
6956 19745235 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6957
2/2
✓ Branch 0 taken 19745235 times.
✓ Branch 1 taken 210303301 times.
230048536 for (int cy = start_y; cy < end_y; cy++)
6958 {
6959
2/2
✓ Branch 0 taken 3193047458 times.
✓ Branch 1 taken 210303301 times.
3403350759 for (int cx = start_x; cx < end_x; cx++)
6960 {
6961 3193047458 int i = cx + cy*16;
6962
2/2
✓ Branch 0 taken 373728646 times.
✓ Branch 1 taken 2819318812 times.
3193047458 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6963 3193047458 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6964 3193047458 }
6965 210303301 }
6966 19745235 }
6967
6968 16115436 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6969 {
6970
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16115436 times.
16115436 if (!show_layers[0])
6971 {
6972 return;
6973 }
6974
6975 16115436 x -= viewport.x;
6976 16115436 y -= viewport.y;
6977
6978
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16115436 times.
32367190 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6979 16251754 mapscr* scr = screen_handles[0].base_scr;
6980
1/2
✓ Branch 0 taken 16251754 times.
✗ Branch 1 not taken.
16251754 if (!scr->is_valid())
6981 return;
6982
6983
2/2
✓ Branch 0 taken 123016 times.
✓ Branch 1 taken 16128738 times.
16251754 if(scr->door[0]==dBOMBED)
6984 {
6985 123016 over_door(scr, dest, 39, up, offx+x, offy+y);
6986 123016 }
6987
6988
2/2
✓ Branch 0 taken 139794 times.
✓ Branch 1 taken 16111960 times.
16251754 if(scr->door[1]==dBOMBED)
6989 {
6990 139794 over_door(scr, dest, 135, down, offx+x, offy+y);
6991 139794 }
6992
6993
2/2
✓ Branch 0 taken 155862 times.
✓ Branch 1 taken 16095892 times.
16251754 if(scr->door[2]==dBOMBED)
6994 {
6995 155862 over_door(scr, dest, 66, left, offx+x, offy+y);
6996 155862 }
6997
6998
2/2
✓ Branch 0 taken 132250 times.
✓ Branch 1 taken 16119504 times.
16251754 if(scr->door[3]==dBOMBED)
6999 {
7000 132250 over_door(scr, dest, 77, right, offx+x, offy+y);
7001 132250 }
7002 16251754 });
7003 16115436 }
7004
7005 3493481 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
7006 {
7007
2/4
✓ Branch 0 taken 3493481 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3493481 times.
✗ Branch 3 not taken.
3493481 if (!scr->is_valid() || !show_layers[0])
7008 return;
7009
7010 3493481 x -= viewport.x;
7011 3493481 y -= viewport.y;
7012
7013
2/2
✓ Branch 0 taken 37338 times.
✓ Branch 1 taken 3456143 times.
3493481 if(scr->door[0]==dBOMBED)
7014 {
7015 37338 over_door(scr,dest,39,up,x,y);
7016 37338 }
7017
7018
2/2
✓ Branch 0 taken 36047 times.
✓ Branch 1 taken 3457434 times.
3493481 if(scr->door[1]==dBOMBED)
7019 {
7020 36047 over_door(scr,dest,135,down,x,y);
7021 36047 }
7022
7023
2/2
✓ Branch 0 taken 40440 times.
✓ Branch 1 taken 3453041 times.
3493481 if(scr->door[2]==dBOMBED)
7024 {
7025 40440 over_door(scr,dest,66,left,x,y);
7026 40440 }
7027
7028
2/2
✓ Branch 0 taken 37063 times.
✓ Branch 1 taken 3456418 times.
3493481 if(scr->door[3]==dBOMBED)
7029 {
7030 37063 over_door(scr,dest,77,right,x,y);
7031 37063 }
7032 3493481 }
7033 262867050 static inline bool standing_on_z(newcombo const& cmb, zfix const& standing_z_state)
7034 {
7035
1/2
✓ Branch 0 taken 262867050 times.
✗ Branch 1 not taken.
262867050 if (cmb.dive_under_level)
7036 {
7037 if (standing_z_state <= -cmb.dive_under_level)
7038 return true;
7039 }
7040
7041 262867050 zfix cmb_z, cmb_z_step;
7042
4/4
✓ Branch 0 taken 92789 times.
✓ Branch 1 taken 262774261 times.
✓ Branch 2 taken 88819 times.
✓ Branch 3 taken 3970 times.
262867050 if(cmb.type == cCSWITCHBLOCK && (cmb.usrflags & cflag9))
7043 {
7044 3970 cmb_z = zslongToFix(cmb.attributes[2]);
7045
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3970 times.
3970 cmb_z_step = zslongToFix(zc_max(0,cmb.attributes[3]));
7046 3970 }
7047
2/2
✓ Branch 0 taken 1983 times.
✓ Branch 1 taken 262861097 times.
262863080 else if(cmb.genflags & cflag3)
7048 {
7049 1983 cmb_z = cmb.z_height;
7050
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1983 times.
1983 cmb_z_step = zc_max(0_zf,cmb.z_step_height);
7051 1983 }
7052 262861097 else return false;
7053
7054
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5953 times.
5953 if (standing_z_state == STANDING_Z_MAX) // 'infinity'
7055 return true;
7056
2/2
✓ Branch 0 taken 1149 times.
✓ Branch 1 taken 4804 times.
5953 if (!cmb_z) return false; // infinite height
7057
7058 4804 return (cmb_z - cmb_z_step) <= standing_z_state;
7059 262867050 }
7060 62119422 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
7061 {
7062 62119422 return _walkflag(zx,zy,cnt,0_zf);
7063 }
7064
7065 142525606 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& standing_z_state, bool is_temp_screens)
7066 {
7067 142525606 int x = zx.getRound(), y = zy.getRound();
7068 142525606 int pos = COMBOPOS(x % 256, y % 176);
7069 142525606 const newcombo& c = combobuf[s0->data[pos]];
7070 142525606 const newcombo& c1 = combobuf[s1->data[pos]];
7071 142525606 const newcombo& c2 = combobuf[s2->data[pos]];
7072
4/4
✓ Branch 0 taken 140435828 times.
✓ Branch 1 taken 2089778 times.
✓ Branch 2 taken 140426368 times.
✓ Branch 3 taken 9460 times.
285281202 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
7073
4/4
✓ Branch 0 taken 114995 times.
✓ Branch 1 taken 140541363 times.
✓ Branch 2 taken 2210232 times.
✓ Branch 3 taken 4001 times.
142525606 (iswater_type(c2.type))) && DRIEDLAKE);
7074 142755596 int32_t b=1;
7075
2/2
✓ Branch 0 taken 70383912 times.
✓ Branch 1 taken 72371684 times.
142755596 if(x&8) b<<=2;
7076
2/2
✓ Branch 0 taken 66734748 times.
✓ Branch 1 taken 76020848 times.
142755596 if(y&8) b<<=1;
7077
7078 142755596 int32_t cwalkflag = c.walk;
7079
4/4
✓ Branch 0 taken 142640592 times.
✓ Branch 1 taken 115004 times.
✓ Branch 2 taken 142640428 times.
✓ Branch 3 taken 164 times.
142755596 if(is_temp_screens && standing_on_z(c,standing_z_state)) cwalkflag &= (c.walk>>4)^0xF;
7080
8/10
✓ Branch 0 taken 57502 times.
✓ Branch 1 taken 142697930 times.
✓ Branch 2 taken 2204764 times.
✓ Branch 3 taken 2147262 times.
✓ Branch 4 taken 2204764 times.
✓ Branch 5 taken 142640428 times.
✓ Branch 6 taken 2204764 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2204764 times.
✗ Branch 9 not taken.
142755432 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
7081
2/2
✓ Branch 0 taken 63123625 times.
✓ Branch 1 taken 79516967 times.
142640592 if (s1 != s0)
7082 {
7083
3/4
✓ Branch 0 taken 79516967 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 79516349 times.
✓ Branch 3 taken 618 times.
79516967 if(is_temp_screens && standing_on_z(c1,standing_z_state)) cwalkflag &= (c1.walk>>4)^0xF;
7084
4/10
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 79504620 times.
✓ Branch 2 taken 11729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11729 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
79516349 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
7085
2/2
✓ Branch 0 taken 71255 times.
✓ Branch 1 taken 79445094 times.
79516349 else if (c1.type == cBRIDGE)
7086 {
7087
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71255 times.
71255 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
7088 {
7089 71255 int efflag = (c1.walk & 0xF0)>>4;
7090 71255 int newsolid = (c1.walk & 0xF);
7091 71255 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
7092 71255 }
7093 else cwalkflag &= c1.walk;
7094 71255 }
7095
3/8
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 79433365 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11729 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
79445094 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
7096 79445094 else cwalkflag |= c1.walk;
7097 79516967 }
7098
2/2
✓ Branch 0 taken 101931101 times.
✓ Branch 1 taken 40709491 times.
142640592 if (s2 != s0)
7099 {
7100
2/4
✓ Branch 0 taken 40709491 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40709491 times.
✗ Branch 3 not taken.
40709491 if(is_temp_screens && standing_on_z(c2,standing_z_state)) cwalkflag &= (c2.walk>>4)^0xF;
7101
7/10
✓ Branch 0 taken 5889 times.
✓ Branch 1 taken 40703602 times.
✓ Branch 2 taken 5889 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3735 times.
✓ Branch 5 taken 2154 times.
✓ Branch 6 taken 3735 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 3735 times.
40709491 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
7102
2/2
✓ Branch 0 taken 16725 times.
✓ Branch 1 taken 40689031 times.
40705756 else if (c2.type == cBRIDGE)
7103 {
7104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16725 times.
16725 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
7105 {
7106 16725 int efflag = (c2.walk & 0xF0)>>4;
7107 16725 int newsolid = (c2.walk & 0xF);
7108 16725 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
7109 16725 }
7110 else cwalkflag &= c2.walk;
7111 16725 }
7112
3/8
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 40686877 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2154 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
40689031 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
7113 40689031 else cwalkflag |= c2.walk;
7114 40709491 }
7115
7116
4/4
✓ Branch 0 taken 30792980 times.
✓ Branch 1 taken 111847612 times.
✓ Branch 2 taken 704 times.
✓ Branch 3 taken 30792276 times.
142640592 if((cwalkflag&b) && !dried)
7117 30792276 return true;
7118
7119
3/4
✓ Branch 0 taken 111848316 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 111779126 times.
✓ Branch 3 taken 69190 times.
111848316 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
7120
7121 111779126 return false;
7122 142640592 }
7123
7124 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
7125 142640592 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& standing_z_state)
7126 {
7127 142640592 int x = zx.getRound(), y = zy.getRound();
7128 142640592 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
7129 142640592 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
7130 142640592 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
7131
2/2
✓ Branch 0 taken 63123625 times.
✓ Branch 1 taken 79516967 times.
142640592 if (!s1->valid) s1 = s0;
7132
2/2
✓ Branch 0 taken 101931101 times.
✓ Branch 1 taken 40709491 times.
142640592 if (!s2->valid) s2 = s0;
7133 142640592 return _walkflag_new(s0, s1, s2, zx, zy, standing_z_state, true);
7134 }
7135
7136 138118540 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& standing_z_state)
7137 {
7138 138118540 int max_x = world_w;
7139 138118540 int max_y = world_h;
7140
2/2
✓ Branch 0 taken 78162632 times.
✓ Branch 1 taken 59955908 times.
138118540 if (!get_qr(qr_LTTPWALK))
7141 {
7142 59955908 max_x -= 7;
7143 59955908 max_y -= 7;
7144 59955908 }
7145
4/4
✓ Branch 0 taken 137846172 times.
✓ Branch 1 taken 272368 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 137762904 times.
138118540 if (x < 0 || y < 0) return false;
7146
2/2
✓ Branch 0 taken 323466 times.
✓ Branch 1 taken 137439438 times.
137762904 if (x >= max_x) return false;
7147
3/4
✓ Branch 0 taken 571659 times.
✓ Branch 1 taken 136867779 times.
✓ Branch 2 taken 571659 times.
✗ Branch 3 not taken.
137439438 if (x >= max_x - 8 && cnt == 2) return false;
7148
2/2
✓ Branch 0 taken 136885361 times.
✓ Branch 1 taken 554077 times.
137439438 if (y >= max_y) return false;
7149
7150
4/4
✓ Branch 0 taken 30743246 times.
✓ Branch 1 taken 106142115 times.
✓ Branch 2 taken 100386884 times.
✓ Branch 3 taken 5755231 times.
136885361 return _walkflag_new(x, y, standing_z_state) || (cnt != 1 && _walkflag_new(x + 8, y, standing_z_state));
7151 138118540 }
7152
7153 105095804 static bool effectflag(int32_t x, int32_t y, int32_t layer)
7154 {
7155 105095804 mapscr* s0 = get_scr_for_world_xy(x, y);
7156 105095804 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
7157 105095804 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
7158
2/2
✓ Branch 0 taken 57657645 times.
✓ Branch 1 taken 47438159 times.
105095804 if (!s1->valid) s1 = s0;
7159
2/2
✓ Branch 0 taken 24624446 times.
✓ Branch 1 taken 80471358 times.
105095804 if (!s2->valid) s2 = s0;
7160
7161 105095804 int pos = COMBOPOS(x % 256, y % 176);
7162 105095804 const newcombo& c = combobuf[s0->data[pos]];
7163 105095804 const newcombo& c1 = combobuf[s1->data[pos]];
7164 105095804 const newcombo& c2 = combobuf[s2->data[pos]];
7165
4/4
✓ Branch 0 taken 104101971 times.
✓ Branch 1 taken 993833 times.
✓ Branch 2 taken 104100691 times.
✓ Branch 3 taken 1280 times.
210191608 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
7166
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 104100691 times.
✓ Branch 2 taken 993593 times.
✓ Branch 3 taken 1520 times.
105095804 (iswater_type(c2.type))) && DRIEDLAKE);
7167 105095804 int32_t b=1;
7168
2/2
✓ Branch 0 taken 53185012 times.
✓ Branch 1 taken 51910792 times.
105095804 if(x&8) b<<=2;
7169
2/2
✓ Branch 0 taken 44669950 times.
✓ Branch 1 taken 60425854 times.
105095804 if(y&8) b<<=1;
7170
7171 105095804 int32_t cwalkflag = (c.walk>>4);
7172
2/2
✓ Branch 0 taken 80325133 times.
✓ Branch 1 taken 24770671 times.
105095804 if (layer == 0) cwalkflag = (c1.walk>>4);
7173
2/2
✓ Branch 0 taken 80326809 times.
✓ Branch 1 taken 24768995 times.
105095804 if (layer == 1) cwalkflag = (c2.walk>>4);
7174 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
7175
4/4
✓ Branch 0 taken 57657645 times.
✓ Branch 1 taken 47438159 times.
✓ Branch 2 taken 24572336 times.
✓ Branch 3 taken 33085309 times.
105095804 if (s1 != s0 && layer < 0)
7176 {
7177
2/2
✓ Branch 0 taken 24556122 times.
✓ Branch 1 taken 16214 times.
24572336 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
7178 24572336 }
7179
4/4
✓ Branch 0 taken 24624446 times.
✓ Branch 1 taken 80471358 times.
✓ Branch 2 taken 17774749 times.
✓ Branch 3 taken 6849697 times.
105095804 if (s2 != s0 && layer < 1)
7180 {
7181
2/2
✓ Branch 0 taken 17762865 times.
✓ Branch 1 taken 11884 times.
17774749 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
7182 17774749 }
7183
7184
2/2
✓ Branch 0 taken 104917800 times.
✓ Branch 1 taken 178004 times.
105095804 return (cwalkflag&b) ? !dried : false;
7185 }
7186
7187 105468966 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
7188 {
7189 DCHECK(cnt == 0 || cnt == 1);
7190 105468966 int max_x = world_w;
7191 105468966 int max_y = world_h;
7192
3/4
✓ Branch 0 taken 45773309 times.
✓ Branch 1 taken 59695657 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45773309 times.
105468966 if (!get_qr(qr_LTTPWALK) && !notLink)
7193 {
7194 45773309 max_x -= 7;
7195 45773309 max_y -= 7;
7196 45773309 }
7197
4/4
✓ Branch 0 taken 105468214 times.
✓ Branch 1 taken 752 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 105468010 times.
105468966 if (x < 0 || y < 0) return false;
7198
2/2
✓ Branch 0 taken 816 times.
✓ Branch 1 taken 105467194 times.
105468010 if (x >= max_x) return false;
7199
3/4
✓ Branch 0 taken 526224 times.
✓ Branch 1 taken 104940970 times.
✓ Branch 2 taken 526224 times.
✗ Branch 3 not taken.
105467194 if (x >= max_x - 8 && cnt == 2) return false;
7200
2/2
✓ Branch 0 taken 371390 times.
✓ Branch 1 taken 105095804 times.
105467194 if (y >= max_y) return false;
7201
7202
3/4
✓ Branch 0 taken 104917174 times.
✓ Branch 1 taken 178630 times.
✓ Branch 2 taken 178630 times.
✗ Branch 3 not taken.
105095804 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
7203 105468966 }
7204
7205 // used by mapdata->isSolid(x,y) in ZScript
7206 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7207 {
7208 int x = zx.getRound(), y = zy.getRound();
7209 {
7210 int max_x = 256;
7211 int max_y = 176;
7212 if (!get_qr(qr_LTTPWALK))
7213 {
7214 max_x -= 7;
7215 max_y -= 7;
7216 }
7217 if (x < 0 || y < 0) return false;
7218 if (x >= max_x) return false;
7219 if (x >= max_x - 8 && cnt == 2) return false;
7220 if (y >= max_y) return false;
7221 }
7222
7223 const mapscr *s1, *s2;
7224 s1 = s2 = m;
7225
7226 if ( m->layermap[0] > 0 && m->layermap[0] <= map_count )
7227 {
7228 const mapscr* s = get_canonical_scr(m->layermap[0] - 1, m->layerscreen[0]);
7229 if (s->is_valid())
7230 s1 = s;
7231 }
7232
7233 if ( m->layermap[1] > 0 && m->layermap[1] <= map_count )
7234 {
7235 const mapscr* s = get_canonical_scr(m->layermap[1] - 1, m->layerscreen[1]);
7236 if (s->is_valid())
7237 s2 = s;
7238 }
7239
7240 zfix unused;
7241 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
7242 }
7243
7244 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
7245 {
7246 DCHECK_LAYER_NEG1_INDEX(layer);
7247 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7248 if (!m->is_valid()) return false;
7249 return _walkflag_layer(x, y, cnt, m);
7250 }
7251
7252 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
7253 {
7254 int x = zx.getRound(), y = zy.getRound();
7255
7256 if (!get_qr(qr_LTTPWALK))
7257 {
7258 max_x -= 7;
7259 max_y -= 7;
7260 }
7261 if (x < 0 || y < 0) return false;
7262 if (x >= max_x) return false;
7263 if (x >= max_x - 8 && cnt == 2) return false;
7264 if (y >= max_y) return false;
7265
7266 if(!m) return true;
7267
7268 int pos = COMBOPOS(x%256, y%176);
7269 const newcombo* c = &combobuf[m->data[pos]];
7270 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7271 int32_t b=1;
7272
7273 if(x&8) b<<=2;
7274
7275 if(y&8) b<<=1;
7276
7277 if((c->walk&b) && !dried)
7278 return true;
7279
7280 if(cnt==1) return false;
7281
7282 ++pos;
7283
7284 if(!(x&8))
7285 b<<=2;
7286 else
7287 {
7288 c = &combobuf[m->data[pos]];
7289 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7290 b=1;
7291
7292 if(y&8) b<<=1;
7293 }
7294
7295 return (c->walk&b) ? !dried : false;
7296 }
7297
7298 //Only check the given mapscr*, not its layer 1&2
7299 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7300 {
7301 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
7302 }
7303
7304 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7305 {
7306 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
7307 }
7308
7309 447898 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
7310 {
7311 DCHECK_LAYER_NEG1_INDEX(layer);
7312 447898 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7313
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 446136 times.
447898 if (!m->is_valid()) return false;
7314 446136 return _effectflag_layer(x, y, cnt, m, notLink);
7315 447898 }
7316
7317 519213 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
7318 {
7319 519213 int max_x = world_w;
7320 519213 int max_y = world_h;
7321
3/4
✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 469211 times.
✓ Branch 2 taken 50002 times.
✗ Branch 3 not taken.
519213 if (!get_qr(qr_LTTPWALK) && !notLink)
7322 {
7323 max_x -= 7;
7324 max_y -= 7;
7325 }
7326
2/4
✓ Branch 0 taken 519213 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 519213 times.
519213 if (x < 0 || y < 0) return false;
7327
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 519213 times.
519213 if (x >= max_x) return false;
7328
3/4
✓ Branch 0 taken 1342 times.
✓ Branch 1 taken 517871 times.
✓ Branch 2 taken 1342 times.
✗ Branch 3 not taken.
519213 if (x >= max_x - 8 && cnt == 2) return false;
7329
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 519213 times.
519213 if (y >= max_y) return false;
7330
7331
1/2
✓ Branch 0 taken 519213 times.
✗ Branch 1 not taken.
519213 if (!m) return true;
7332
7333 519213 int pos = COMBOPOS(x%256, y%176);
7334 519213 const newcombo* c = &combobuf[m->data[pos]];
7335
3/4
✓ Branch 0 taken 518813 times.
✓ Branch 1 taken 400 times.
✓ Branch 2 taken 400 times.
✗ Branch 3 not taken.
519613 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7336 519213 int32_t b=1;
7337
7338
2/2
✓ Branch 0 taken 276528 times.
✓ Branch 1 taken 242685 times.
519213 if(x&8) b<<=2;
7339
7340
2/2
✓ Branch 0 taken 220331 times.
✓ Branch 1 taken 298882 times.
519213 if(y&8) b<<=1;
7341
7342
3/4
✓ Branch 0 taken 450224 times.
✓ Branch 1 taken 68989 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 450224 times.
519213 if(((c->walk>>4)&b) && !dried)
7343 450224 return true;
7344
7345
1/2
✓ Branch 0 taken 68989 times.
✗ Branch 1 not taken.
68989 if(cnt==1) return false;
7346
7347 ++pos;
7348
7349 if(!(x&8))
7350 b<<=2;
7351 else
7352 {
7353 c = &combobuf[m->data[pos]];
7354 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7355 b=1;
7356
7357 if(y&8) b<<=1;
7358 }
7359
7360 return ((c->walk>>4)&b) ? !dried : false;
7361 519213 }
7362
7363 860420 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7364 {
7365 860420 int max_x = world_w;
7366 860420 int max_y = world_h;
7367
2/2
✓ Branch 0 taken 165182 times.
✓ Branch 1 taken 695238 times.
860420 if (!get_qr(qr_LTTPWALK))
7368 {
7369 695238 max_x -= 7;
7370 695238 max_y -= 7;
7371 695238 }
7372
2/4
✓ Branch 0 taken 860420 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 860420 times.
860420 if (x < 0 || y < 0) return false;
7373
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if (x >= max_x) return false;
7374
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
860420 if (x >= max_x - 8 && cnt == 2) return false;
7375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if (y >= max_y) return false;
7376
7377
3/4
✓ Branch 0 taken 17860 times.
✓ Branch 1 taken 842560 times.
✓ Branch 2 taken 842560 times.
✗ Branch 3 not taken.
860420 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7378 860420 }
7379
7380 860420 bool water_walkflag(int32_t x, int32_t y)
7381 {
7382 860420 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7383 860420 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7384 860420 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7385
7386 860420 int32_t b=1;
7387
2/2
✓ Branch 0 taken 439102 times.
✓ Branch 1 taken 421318 times.
860420 if(x&8) b<<=2;
7388
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if(y&8) b<<=1;
7389
7390
2/2
✓ Branch 0 taken 74192 times.
✓ Branch 1 taken 786228 times.
860420 if(get_qr(qr_NO_SOLID_SWIM))
7391 {
7392
2/2
✓ Branch 0 taken 474 times.
✓ Branch 1 taken 73718 times.
74192 if(c.walk&b)
7393 474 return true;
7394
7395
2/2
✓ Branch 0 taken 914 times.
✓ Branch 1 taken 72804 times.
73718 if(c1.walk&b)
7396 914 return true;
7397
7398
2/2
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 72733 times.
72804 if(c2.walk&b)
7399 71 return true;
7400 72733 }
7401 else
7402 {
7403
4/4
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 750095 times.
✓ Branch 2 taken 19762 times.
✓ Branch 3 taken 16371 times.
786228 if((c.walk&b) && !iswater_type(c.type))
7404 16371 return true;
7405
7406
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 769840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
769857 if((c1.walk&b) && !iswater_type(c1.type))
7407 17 return true;
7408
7409
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 769827 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
769840 if((c2.walk&b) && !iswater_type(c2.type))
7410 13 return true;
7411 }
7412
7413 842560 return false;
7414 860420 }
7415
7416 589472 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7417 {
7418
2/2
✓ Branch 0 taken 100391 times.
✓ Branch 1 taken 489081 times.
589472 if(dlevel)
7419
8/8
✓ Branch 0 taken 487640 times.
✓ Branch 1 taken 1441 times.
✓ Branch 2 taken 484322 times.
✓ Branch 3 taken 3318 times.
✓ Branch 4 taken 482605 times.
✓ Branch 5 taken 1717 times.
✓ Branch 6 taken 4386 times.
✓ Branch 7 taken 478219 times.
489081 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7420 10862 return true;
7421
7422
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 578608 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
578610 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7423 return true;
7424
7425
8/8
✓ Branch 0 taken 578324 times.
✓ Branch 1 taken 286 times.
✓ Branch 2 taken 578081 times.
✓ Branch 3 taken 243 times.
✓ Branch 4 taken 577870 times.
✓ Branch 5 taken 211 times.
✓ Branch 6 taken 396 times.
✓ Branch 7 taken 577474 times.
578610 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7426 1136 return true;
7427
7428 // for(int32_t i=0; i<4; i++)
7429
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 576633 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
577474 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7430 36 return true;
7431
7432
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 577437 times.
577438 if (collide_object(x, y,cnt*8, 1))
7433 1 return true;
7434
7435 577437 return _walkflag(x,y,cnt);
7436 589472 }
7437
7438 12220 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7439 {
7440 // 16 pixel buffer to account for slopes that are on bordering screens.
7441
4/8
✓ Branch 0 taken 12220 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12220 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12220 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12220 times.
12220 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7442 return true;
7443
7444 // for(int32_t i=0; i<4; i++)
7445
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12220 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12220 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7446 return true;
7447
7448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12220 times.
12220 if (collide_object(x, y,cnt*8, 1, ign))
7449 return true;
7450
7451 12220 return _walkflag(x,y,cnt);
7452 12220 }
7453
7454 39559 void map_bkgsfx(bool on)
7455 {
7456
2/2
✓ Branch 0 taken 39538 times.
✓ Branch 1 taken 21 times.
39559 if(on)
7457 {
7458 39538 cont_sfx(hero_scr->oceansfx);
7459
7460
4/4
✓ Branch 0 taken 369 times.
✓ Branch 1 taken 39169 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 54 times.
39538 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&(1 << li_boss_killed)))
7461 315 cont_sfx(hero_scr->bosssfx);
7462 39538 }
7463 else
7464 {
7465 21 adjust_sfx(hero_scr->oceansfx,128,false);
7466 21 adjust_sfx(hero_scr->bosssfx,128,false);
7467
7468
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7469 {
7470
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7471 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7472 114 }
7473 }
7474 39559 }
7475
7476 261 void toggle_switches(dword flags, bool entry)
7477 {
7478
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 261 times.
261 if(!flags) return; //No flags to toggle
7479
7480 522 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7481 261 toggle_switches(flags, entry, create_screen_handles(scr));
7482 261 });
7483 261 }
7484 55176 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7485 {
7486
2/2
✓ Branch 0 taken 931 times.
✓ Branch 1 taken 54245 times.
55176 if(!flags) return; //No flags to toggle
7487
7488 931 mapscr* m = screen_handles[0].base_scr;
7489 931 int screen = m->screen;
7490 931 bool is_active_screen = is_in_current_region(m);
7491
7492 525235 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7493 524304 byte togglegrid[176] = {0};
7494 524304 mapscr* scr = rpos_handle.scr;
7495 524304 int lyr = rpos_handle.layer;
7496 524304 int pos = rpos_handle.pos;
7497 524304 newcombo const& cmb = combobuf[scr->data[pos]];
7498
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 484880 times.
524304 if(is_active_screen)
7499
1/2
✓ Branch 0 taken 484880 times.
✗ Branch 1 not taken.
641011 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7500
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 156131 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
156131 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7501 }, ctrigSWITCHSTATE);
7502
3/4
✓ Branch 0 taken 523592 times.
✓ Branch 1 taken 712 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2809 times.
524304 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32
7503
2/2
✓ Branch 0 taken 2809 times.
✓ Branch 1 taken 521495 times.
524304 && !(cmb.usrflags & cflag11)) //global state
7504 {
7505
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2363 times.
2809 if(flags&(1<<cmb.attribytes[0]))
7506 {
7507 2363 set<int32_t> oldData;
7508 //Increment the combo/cset by the attributes
7509 2363 int32_t cmbofs = (cmb.attributes[0]/10000L);
7510 2363 int32_t csofs = (cmb.attributes[1]/10000L);
7511
1/2
✓ Branch 0 taken 2363 times.
✗ Branch 1 not taken.
2363 oldData.insert(scr->data[pos]);
7512
1/2
✓ Branch 0 taken 2363 times.
✗ Branch 1 not taken.
2363 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7513 2363 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7514
4/4
✓ Branch 0 taken 1444 times.
✓ Branch 1 taken 919 times.
✓ Branch 2 taken 1206 times.
✓ Branch 3 taken 238 times.
2363 if(entry && (cmb.usrflags&cflag8))
7515 {
7516 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7517
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7518 {
7519 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7520 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7521 if(oldData.find(cid) != oldData.end())
7522 break;
7523
7524 scr->data[pos] = cid;
7525 if(!(tmp->animflags & AF_CYCLENOCSET))
7526 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7527 oldData.insert(cid);
7528 tmp = &combobuf[cid];
7529 }
7530 238 }
7531 2363 int32_t cmbid = scr->data[pos];
7532
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2322 times.
2363 if(combobuf[cmbid].animflags & AF_CYCLE)
7533 {
7534 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7535 41 combobuf[cmbid].cur_frame=0;
7536 41 combobuf[cmbid].aclk = 0;
7537
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7538 41 }
7539 2363 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7540
2/2
✓ Branch 0 taken 560 times.
✓ Branch 1 taken 1803 times.
2363 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7541
2/2
✓ Branch 0 taken 12621 times.
✓ Branch 1 taken 1803 times.
14424 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7542 {
7543
2/2
✓ Branch 0 taken 1803 times.
✓ Branch 1 taken 10818 times.
12621 if(lyr==lyr2) continue;
7544
2/2
✓ Branch 0 taken 344 times.
✓ Branch 1 taken 10474 times.
10818 if(!(cmb.usrflags&(1<<lyr2))) continue;
7545
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(togglegrid[pos]&(1<<lyr2)) continue;
7546
7547 344 mapscr* scr_2 = screen_handles[lyr2].scr;
7548
2/4
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 344 times.
344 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7549 continue;
7550 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7551
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7552 && cmb_2.attribytes[0] < 32 && (flags&(1<<cmb_2.attribytes[0])))
7553 continue; //This is a switch/block that will be hit later in the loop!
7554 344 set<int32_t> oldData2;
7555 //Increment the combo/cset by the original cmb's attributes
7556
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7557
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7558 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7559
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7560 {
7561 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7562 while(tmp->can_cycle())
7563 {
7564 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7565 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7566 if(oldData2.find(cid) != oldData2.end())
7567 break;
7568
7569 scr_2->data[pos] = cid;
7570 if(!(tmp->animflags & AF_CYCLENOCSET))
7571 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7572 oldData2.insert(cid);
7573 tmp = &combobuf[cid];
7574 }
7575 }
7576 344 int32_t cmbid2 = scr_2->data[pos];
7577
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7578 {
7579 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7580 combobuf[cmbid2].cur_frame=0;
7581 combobuf[cmbid2].aclk = 0;
7582 combo_caches::drawing.refresh(cmbid2);
7583 }
7584 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7585 344 }
7586
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 560 times.
✓ Branch 2 taken 1803 times.
2363 }
7587 2249 }
7588 524304 });
7589
7590
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 412 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
931 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7591 {
7592 newcombo const& cmb = combobuf[mblock2.bcombo];
7593 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32)
7594 {
7595 if(flags&(1<<cmb.attribytes[0]))
7596 {
7597 //Increment the combo/cset by the attributes
7598 int32_t cmbofs = (cmb.attributes[0]/10000L);
7599 int32_t csofs = (cmb.attributes[1]/10000L);
7600 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7601 mblock2.cs = (mblock2.cs + csofs) & 15;
7602 int32_t cmbid = mblock2.bcombo;
7603 if(combobuf[cmbid].animflags & AF_CYCLE)
7604 {
7605 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7606 combobuf[cmbid].cur_frame=0;
7607 combobuf[cmbid].aclk = 0;
7608 combo_caches::drawing.refresh(cmbid);
7609 }
7610 }
7611 }
7612 }
7613
7614
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 707 times.
931 if (is_active_screen)
7615 {
7616 707 int screen_index_offset = get_region_screen_offset(m->screen);
7617 707 word c = m->numFFC();
7618
2/2
✓ Branch 0 taken 565 times.
✓ Branch 1 taken 707 times.
1272 for (int q = 0; q < c; ++q)
7619 {
7620 565 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7621
1/2
✓ Branch 0 taken 565 times.
✗ Branch 1 not taken.
596 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7622
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
31 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7623 }, ctrigSWITCHSTATE);
7624 565 }
7625 707 }
7626 55176 }
7627
7628 1 void toggle_gswitches(int32_t state, bool entry)
7629 {
7630 2 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7631 1 toggle_gswitches(state, entry, create_screen_handles(scr));
7632 1 });
7633 1 }
7634 1 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7635 {
7636 1 bool states[256] = {false};
7637 1 states[state] = true;
7638 1 toggle_gswitches(states, entry, screen_handles);
7639 1 }
7640 15779680 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7641 {
7642
1/2
✓ Branch 0 taken 15779680 times.
✗ Branch 1 not taken.
15779680 if(!states) return;
7643
7644 15779680 auto& combo_cache = combo_caches::gswitch;
7645 15779680 mapscr* base_scr = screen_handles[0].base_scr;
7646 15779680 int screen = base_scr->screen;
7647 15779680 bool is_active_screen = is_in_current_region(base_scr);
7648 15779680 byte togglegrid[176] = {0};
7649
2/2
✓ Branch 0 taken 15779680 times.
✓ Branch 1 taken 110457760 times.
126237440 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7650 {
7651 110457760 mapscr* scr = screen_handles[lyr].scr;
7652
2/2
✓ Branch 0 taken 35884114 times.
✓ Branch 1 taken 74573646 times.
110457760 if (!scr)
7653 74573646 continue;
7654
7655
2/2
✓ Branch 0 taken 35884114 times.
✓ Branch 1 taken 6315604064 times.
6351488178 for(int32_t pos = 0; pos < 176; ++pos)
7656 {
7657 6315604064 int cid = scr->data[pos];
7658 6315604064 auto& mini_cmb = combo_cache.minis[cid];
7659
7660
2/2
✓ Branch 0 taken 2910160 times.
✓ Branch 1 taken 6312693904 times.
6315604064 if (is_active_screen)
7661 {
7662
2/2
✓ Branch 0 taken 6312692022 times.
✓ Branch 1 taken 1882 times.
6312693904 if (mini_cmb.trigger_global_state)
7663 {
7664 1882 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7665
1/2
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
3764 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7666
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1882 times.
1882 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7667 }, ctrigSWITCHSTATE);
7668 1882 }
7669 6312693904 }
7670
7671
2/2
✓ Branch 0 taken 55356 times.
✓ Branch 1 taken 6315548708 times.
6315604064 if (!mini_cmb.has_global_state)
7672 6315548708 continue;
7673
7674 55356 newcombo const& cmb = combobuf[cid];
7675
2/4
✓ Branch 0 taken 55356 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 55356 times.
55356 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7676 {
7677 if(states[cmb.attribytes[0]])
7678 {
7679 set<int32_t> oldData;
7680 //Increment the combo/cset by the attributes
7681 int32_t cmbofs = (cmb.attributes[0]/10000L);
7682 int32_t csofs = (cmb.attributes[1]/10000L);
7683 oldData.insert(scr->data[pos]);
7684 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7685 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7686 if(entry && (cmb.usrflags&cflag8))
7687 {
7688 newcombo const* tmp = &combobuf[scr->data[pos]];
7689 while(tmp->can_cycle())
7690 {
7691 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7692 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7693 if(oldData.find(cid) != oldData.end())
7694 break;
7695 scr->data[pos] = cid;
7696 if(!(tmp->animflags & AF_CYCLENOCSET))
7697 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7698 oldData.insert(cid);
7699 tmp = &combobuf[cid];
7700 }
7701 }
7702 int32_t cmbid = scr->data[pos];
7703 if(combobuf[cmbid].animflags & AF_CYCLE)
7704 {
7705 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7706 combobuf[cmbid].cur_frame=0;
7707 combobuf[cmbid].aclk = 0;
7708 combo_caches::drawing.refresh(cmbid);
7709 }
7710 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7711 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7712 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7713 {
7714 if(lyr==lyr2) continue;
7715 if(!(cmb.usrflags&(1<<lyr2))) continue;
7716 if(togglegrid[pos]&(1<<lyr2)) continue;
7717 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7718 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7719 continue;
7720 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7721 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7722 && (cmb_2.usrflags & cflag11) && (states[cmb_2.attribytes[0]]))
7723 continue; //This is a switch/block that will be hit later in the loop!
7724 set<int32_t> oldData2;
7725 //Increment the combo/cset by the original cmb's attributes
7726 oldData2.insert(scr_2->data[pos]);
7727 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7728 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7729 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7730 {
7731 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7732 while(tmp->can_cycle())
7733 {
7734 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7735 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7736 if(oldData2.find(cid) != oldData2.end())
7737 break;
7738 scr_2->data[pos] = cid;
7739 if(!(tmp->animflags & AF_CYCLENOCSET))
7740 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7741 oldData2.insert(cid);
7742 tmp = &combobuf[cid];
7743 }
7744 }
7745 int32_t cmbid2 = scr_2->data[pos];
7746 if(combobuf[cmbid2].animflags & AF_CYCLE)
7747 {
7748 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7749 combobuf[cmbid2].cur_frame=0;
7750 combobuf[cmbid2].aclk = 0;
7751 combo_caches::drawing.refresh(cmbid2);
7752 }
7753 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7754 }
7755 }
7756 }
7757 55356 }
7758 35884114 }
7759
7760
4/4
✓ Branch 0 taken 554527 times.
✓ Branch 1 taken 15225153 times.
✓ Branch 2 taken 549783 times.
✓ Branch 3 taken 4744 times.
15779680 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7761 {
7762 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7763
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7764 {
7765 if(states[cmb.attribytes[0]])
7766 {
7767 //Increment the combo/cset by the attributes
7768 int32_t cmbofs = (cmb.attributes[0]/10000L);
7769 int32_t csofs = (cmb.attributes[1]/10000L);
7770 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7771 mblock2.cs = (mblock2.cs + csofs) & 15;
7772 int32_t cmbid = mblock2.bcombo;
7773 if(combobuf[cmbid].animflags & AF_CYCLE)
7774 {
7775 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7776 combobuf[cmbid].cur_frame=0;
7777 combobuf[cmbid].aclk = 0;
7778 combo_caches::drawing.refresh(cmbid);
7779 }
7780 }
7781 }
7782 4744 }
7783
7784
2/2
✓ Branch 0 taken 16158 times.
✓ Branch 1 taken 15763522 times.
15779680 if(is_active_screen)
7785 {
7786 15763522 int screen_index_offset = get_region_screen_offset(screen);
7787 15763522 word c = base_scr->numFFC();
7788
2/2
✓ Branch 0 taken 455018214 times.
✓ Branch 1 taken 15763522 times.
470781736 for (int q = 0; q < c; ++q)
7789 {
7790 455018214 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7791
1/2
✓ Branch 0 taken 455018214 times.
✗ Branch 1 not taken.
455251552 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7792
1/2
✓ Branch 0 taken 233338 times.
✗ Branch 1 not taken.
233338 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7793 }, ctrigSWITCHSTATE);
7794 455018214 }
7795 15763522 }
7796 15779680 }
7797 54915 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7798 {
7799 bool states[256];
7800
2/2
✓ Branch 0 taken 14058240 times.
✓ Branch 1 taken 54915 times.
14113155 for(auto q = 0; q < 256; ++q)
7801 {
7802 14058240 states[q] = game->gswitch_timers[q] != 0;
7803 14058240 }
7804 54915 toggle_gswitches(states, true, screen_handles);
7805 54915 }
7806 15335396 void run_gswitch_timers()
7807 {
7808 15335396 bool states[256] = {false};
7809 15335396 auto& m = game->gswitch_timers.mut_inner();
7810
2/2
✓ Branch 0 taken 3921762560 times.
✓ Branch 1 taken 15335396 times.
3937097956 for(auto it = m.begin(); it != m.end();)
7811 {
7812
2/2
✓ Branch 0 taken 3921761960 times.
✓ Branch 1 taken 600 times.
3921762560 if(it->second > 0)
7813
2/2
✓ Branch 0 taken 599 times.
✓ Branch 1 taken 1 times.
600 if(!--it->second)
7814 {
7815 1 states[it->first] = true;
7816 1 it = m.erase(it);
7817 1 continue;
7818 }
7819 3921762559 ++it;
7820 }
7821 31060160 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7822 15724764 toggle_gswitches(states, false, create_screen_handles(scr));
7823 15724764 });
7824 15335396 }
7825 1151 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7826 {
7827
2/2
✓ Branch 0 taken 294656 times.
✓ Branch 1 taken 1151 times.
295807 for(auto q = 0; q < 256; ++q)
7828 {
7829
1/2
✓ Branch 0 taken 294656 times.
✗ Branch 1 not taken.
294656 if(game->gswitch_timers[q] > 0)
7830 game->gswitch_timers[q] = 0;
7831 294656 }
7832 1151 }
7833
7834 /**** View Map ****/
7835
7836 int32_t mapres = 0;
7837 int32_t view_map_show_mode = 3;
7838
7839 129280 bool displayOnMap(int32_t x, int32_t y)
7840 {
7841 129280 int32_t s = (y<<4) + x;
7842 129280 int mi = mapind(cur_map, s);
7843
2/2
✓ Branch 0 taken 70863 times.
✓ Branch 1 taken 58417 times.
129280 if (!(game->maps[mi]&mVISITED))
7844 70863 return false;
7845
7846 // Don't display if not part of DMap
7847
4/4
✓ Branch 0 taken 15807 times.
✓ Branch 1 taken 42610 times.
✓ Branch 2 taken 4750 times.
✓ Branch 3 taken 4311 times.
67478 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7848
1/2
✓ Branch 0 taken 15807 times.
✗ Branch 1 not taken.
15807 (DMaps[cur_dmap].type != dmOVERW) &&
7849
2/2
✓ Branch 0 taken 12631 times.
✓ Branch 1 taken 3176 times.
15807 !(x >= DMaps[cur_dmap].xoff &&
7850
2/2
✓ Branch 0 taken 9061 times.
✓ Branch 1 taken 3570 times.
12631 x < DMaps[cur_dmap].xoff+8 &&
7851 9061 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7852 11057 return false;
7853 else
7854 47360 return true;
7855 129280 }
7856
7857 1010 void ViewMap()
7858 {
7859 1010 ViewingMap = true;
7860
7861 1010 BITMAP* mappic = NULL;
7862 static double scales[17] =
7863 {
7864 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7865 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7866 };
7867
7868 // Cursor position for hero, in absolute map coordinates.
7869 1010 int32_t lx = ((cur_screen & 15) << 8) + HeroX() + 8;
7870 1010 int32_t ly = ((cur_screen >> 4) * 176) + HeroY() + 8;
7871
7872 int32_t px;
7873 int32_t py;
7874
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1010 times.
1010 if (is_in_scrolling_region())
7875 {
7876 // Center the player on the middle of the map view.
7877 px = (16*256/2 - lx) * 2;
7878 py = (8*176/2 - ly) * 2;
7879 }
7880 else
7881 {
7882 // Center the current screen on the middle of the map view.
7883 1010 px = ((8-(cur_screen&15)) << 9) - 256;
7884 1010 py = ((4-(cur_screen>>4)) * 352) - 176;
7885 }
7886
7887 1010 int32_t sc = 6;
7888
7889 1010 bool done=false, redraw=true;
7890
7891 1010 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7892
7893
1/2
✓ Branch 0 taken 1010 times.
✗ Branch 1 not taken.
1010 if(!mappic)
7894 {
7895 enter_sys_pal();
7896 jwin_alert("View Map","Not enough memory.",NULL,NULL,"OK",NULL,13,27,get_zc_font(font_lfont));
7897 exit_sys_pal();
7898 return;
7899 }
7900
7901 1010 clear_to_color(mappic, WHITE);
7902
7903 1010 auto prev_viewport = viewport;
7904 1010 viewport.x = 0;
7905 1010 viewport.y = 0;
7906
7907 // draw the map
7908 1010 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7909 1010 combotile_add_x = 256;
7910 1010 combotile_add_y = 0;
7911 1010 bool classic_draw = get_qr(qr_CLASSIC_DRAWING_ORDER);
7912
2/2
✓ Branch 0 taken 8080 times.
✓ Branch 1 taken 1010 times.
9090 for(int32_t y=0; y<8; y++)
7913 {
7914
2/2
✓ Branch 0 taken 8080 times.
✓ Branch 1 taken 129280 times.
137360 for(int32_t x=0; x<16; x++)
7915 {
7916
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 81920 times.
129280 if (!displayOnMap(x, y))
7917 81920 continue;
7918
7919 47360 int screen = map_scr_xy_to_index(x, y);
7920 47360 auto scrs = loadscr2(screen);
7921 47360 mapscr* scr = &scrs[0];
7922
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if (!scr->is_valid())
7923 continue;
7924
7925 screen_handles_t screen_handles;
7926
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 331520 times.
378880 for (int i = 0; i <= 6; i++)
7927
3/4
✓ Branch 0 taken 331520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114582 times.
✓ Branch 3 taken 216938 times.
331520 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7928
7929 47360 int xx = 0;
7930 47360 int yy = -playing_field_offset;
7931
7932
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 if (!classic_draw)
7933 for (int layer = -7; layer <= -4; ++layer)
7934 do_ffc_layer(screen_bmp, layer, screen_handles[0], xx, yy);
7935
7936
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 if(classic_draw)
7937 {
7938
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 47313 times.
47360 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7939
1/2
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
47 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7940
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7941 47360 }
7942
7943
2/2
✓ Branch 0 taken 213 times.
✓ Branch 1 taken 47147 times.
47360 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7944
1/2
✓ Branch 0 taken 213 times.
✗ Branch 1 not taken.
213 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7945
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7946
7947
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47360 times.
47360 if(!classic_draw)
7948 {
7949 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7950 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7951 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7952 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7953 }
7954
7955
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7956
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7957
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7958
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7959
7960
2/2
✓ Branch 0 taken 47313 times.
✓ Branch 1 taken 47 times.
47360 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7961 {
7962
1/2
✓ Branch 0 taken 47313 times.
✗ Branch 1 not taken.
47313 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7963
1/2
✓ Branch 0 taken 47313 times.
✗ Branch 1 not taken.
47313 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7964 47313 }
7965
7966
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 putscrdoors(scr, screen_bmp, xx, yy);
7967
2/2
✓ Branch 0 taken 43358 times.
✓ Branch 1 taken 4002 times.
47360 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7968 {
7969
1/2
✓ Branch 0 taken 43358 times.
✗ Branch 1 not taken.
43358 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7970
2/2
✓ Branch 0 taken 3462 times.
✓ Branch 1 taken 39896 times.
43358 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7971 {
7972
1/2
✓ Branch 0 taken 3462 times.
✗ Branch 1 not taken.
3462 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7973
1/2
✓ Branch 0 taken 3462 times.
✗ Branch 1 not taken.
3462 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7974 3462 }
7975 43358 }
7976
7977
2/2
✓ Branch 0 taken 47147 times.
✓ Branch 1 taken 213 times.
47360 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7978 {
7979
1/2
✓ Branch 0 taken 47147 times.
✗ Branch 1 not taken.
47147 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7980
1/2
✓ Branch 0 taken 47147 times.
✗ Branch 1 not taken.
47147 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7981 47147 }
7982
7983
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7984
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
7985
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7986
2/2
✓ Branch 0 taken 7464 times.
✓ Branch 1 taken 39896 times.
47360 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
7987 {
7988
1/2
✓ Branch 0 taken 7464 times.
✗ Branch 1 not taken.
7464 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
7989
1/2
✓ Branch 0 taken 7464 times.
✗ Branch 1 not taken.
7464 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
7990 7464 }
7991
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
7992
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
7993
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1680 times.
✓ Branch 3 taken 45680 times.
47360 if(replay_version_check(40))
7994
1/2
✓ Branch 0 taken 1680 times.
✗ Branch 1 not taken.
1680 do_ffc_layer(screen_bmp, -1000, screen_handles[0], xx, yy);
7995
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
7996
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
7997
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
7998
7999
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
8000
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
47360 }
8001 8080 }
8002
8003 1010 viewport = prev_viewport;
8004 1010 combotile_add_x = 0;
8005 1010 combotile_add_y = 0;
8006
8007 1010 destroy_bitmap(screen_bmp);
8008 1010 clear_keybuf();
8009 1010 pause_all_sfx();
8010
8011 // view it
8012 1010 int32_t delay = 0;
8013
8014 1010 do
8015 {
8016
2/2
✓ Branch 0 taken 189085 times.
✓ Branch 1 taken 29891 times.
218976 if (replay_version_check(0, 11))
8017 29891 load_control_state();
8018
8019 218976 int32_t step = int32_t(16.0/scales[sc]);
8020 218976 step = (step>>1) + (step&1);
8021 218976 bool r = cRbtn();
8022
8023
1/2
✓ Branch 0 taken 218976 times.
✗ Branch 1 not taken.
218976 if(cLbtn())
8024 {
8025 step <<= 2;
8026 delay = 0;
8027 }
8028
8029
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 218976 times.
218976 if(r)
8030 {
8031 if(rUp())
8032 {
8033 py+=step;
8034 redraw=true;
8035 }
8036
8037 if(rDown())
8038 {
8039 py-=step;
8040 redraw=true;
8041 }
8042
8043 if(rLeft())
8044 {
8045 px+=step;
8046 redraw=true;
8047 }
8048
8049 if(rRight())
8050 {
8051 px-=step;
8052 redraw=true;
8053 }
8054 }
8055 else
8056 {
8057
2/2
✓ Branch 0 taken 203528 times.
✓ Branch 1 taken 15448 times.
218976 if(Up())
8058 {
8059 15448 py+=step;
8060 15448 redraw=true;
8061 15448 }
8062
8063
2/2
✓ Branch 0 taken 203410 times.
✓ Branch 1 taken 15566 times.
218976 if(Down())
8064 {
8065 15566 py-=step;
8066 15566 redraw=true;
8067 15566 }
8068
8069
2/2
✓ Branch 0 taken 191540 times.
✓ Branch 1 taken 27436 times.
218976 if(Left())
8070 {
8071 27436 px+=step;
8072 27436 redraw=true;
8073 27436 }
8074
8075
2/2
✓ Branch 0 taken 192194 times.
✓ Branch 1 taken 26782 times.
218976 if(Right())
8076 {
8077 26782 px-=step;
8078 26782 redraw=true;
8079 26782 }
8080 }
8081
8082
2/2
✓ Branch 0 taken 22044 times.
✓ Branch 1 taken 196932 times.
218976 if(delay)
8083 22044 --delay;
8084 else
8085 {
8086 196932 bool a = cAbtn();
8087 196932 bool b = cBbtn();
8088
8089
3/4
✓ Branch 0 taken 1786 times.
✓ Branch 1 taken 195146 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1786 times.
196932 if(a && !b)
8090 {
8091
1/2
✓ Branch 0 taken 1786 times.
✗ Branch 1 not taken.
1786 sc=zc_min(sc+1,16);
8092 1786 delay=8;
8093 1786 redraw=true;
8094 1786 }
8095
8096
3/4
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 195960 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 972 times.
196932 if(b && !a)
8097 {
8098
2/2
✓ Branch 0 taken 971 times.
✓ Branch 1 taken 1 times.
972 sc=zc_max(sc-1,0);
8099 972 delay=8;
8100 972 redraw=true;
8101 972 }
8102 }
8103
8104
2/2
✓ Branch 0 taken 218965 times.
✓ Branch 1 taken 11 times.
218976 if(rPbtn())
8105 11 --view_map_show_mode;
8106
8107 218976 px = vbound(px,-4096,4096);
8108 218976 py = vbound(py,-1408,1408);
8109
8110 218976 double scale = scales[sc];
8111
8112
2/2
✓ Branch 0 taken 75341 times.
✓ Branch 1 taken 143635 times.
218976 if(!redraw)
8113 {
8114 143635 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
8115 143635 }
8116 else
8117 {
8118 75341 clear_to_color(framebuf,BLACK);
8119 150682 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
8120 75341 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
8121 75341 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
8122
8123 75341 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
8124 75341 redraw=false;
8125 }
8126
8127 218976 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
8128 218976 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
8129
8130
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 211510 times.
218976 if(view_map_show_mode&1)
8131 {
8132 211510 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
8133 211510 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
8134 211510 }
8135
8136
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 213376 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
218976 if(view_map_show_mode&2 || r)
8137 213376 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
8138
8139
1/2
✓ Branch 0 taken 218976 times.
✗ Branch 1 not taken.
218976 if(r)
8140 {
8141 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
8142 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
8143 }
8144
8145 218976 advanceframe(false, false);
8146
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 189085 times.
218976 if (replay_version_check(11))
8147 189085 load_control_state();
8148
8149
2/2
✓ Branch 0 taken 217967 times.
✓ Branch 1 taken 1009 times.
218976 if (getInput(btnS, INPUT_PRESS | INPUT_IGNORE_DISABLE))
8150 1009 done = true;
8151
8152
2/2
✓ Branch 0 taken 217966 times.
✓ Branch 1 taken 1010 times.
437952 }
8153
2/2
✓ Branch 0 taken 1009 times.
✓ Branch 1 taken 217967 times.
218976 while(!done && !Quit);
8154
8155 1010 ViewingMap = false;
8156 1010 destroy_bitmap(mappic);
8157 1010 resume_all_sfx();
8158 1010 }
8159
8160 1112 int32_t onViewMap()
8161 {
8162
4/6
✓ Branch 0 taken 1112 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1112 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 1010 times.
1112 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
8163 {
8164 1010 clear_to_color(framebuf,BLACK);
8165 1010 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
8166 1010 advanceframe(true);
8167 1010 ViewMap();
8168 1010 }
8169
8170 1112 return D_O_K;
8171 }
8172
8173 38924622 bool isGrassType(int32_t type)
8174 {
8175
2/2
✓ Branch 0 taken 38166509 times.
✓ Branch 1 taken 758113 times.
38924622 switch(type)
8176 {
8177 case cTALLGRASS:
8178 case cTALLGRASSNEXT:
8179 case cTALLGRASSTOUCHY:
8180 758113 return true;
8181 }
8182
8183 38166509 return false;
8184 38924622 }
8185
8186 25672 bool isFlowersType(int32_t type)
8187 {
8188
2/2
✓ Branch 0 taken 21332 times.
✓ Branch 1 taken 4340 times.
25672 switch(type)
8189 {
8190 case cFLOWERS:
8191 case cFLOWERSTOUCHY:
8192 4340 return true;
8193 }
8194
8195 21332 return false;
8196 25672 }
8197
8198 bool isGenericType(int32_t type)
8199 {
8200 switch(type)
8201 {
8202 case cTRIGGERGENERIC:
8203 return true;
8204 }
8205
8206 return false;
8207 }
8208
8209 30978 bool isBushType(int32_t type)
8210 {
8211
2/2
✓ Branch 0 taken 25672 times.
✓ Branch 1 taken 5306 times.
30978 switch(type)
8212 {
8213 case cBUSH:
8214 case cBUSHNEXT:
8215 case cBUSHTOUCHY:
8216 case cBUSHNEXTTOUCHY:
8217
8218 5306 return true;
8219 }
8220
8221 25672 return false;
8222 30978 }
8223
8224 bool isSlashType(int32_t type)
8225 {
8226 switch(type)
8227 {
8228 case cSLASH:
8229 case cSLASHITEM:
8230 case cSLASHTOUCHY:
8231 case cSLASHITEMTOUCHY:
8232 case cSLASHNEXT:
8233 case cSLASHNEXTITEM:
8234 case cSLASHNEXTTOUCHY:
8235 case cSLASHNEXTITEMTOUCHY:
8236 return true;
8237 }
8238
8239 return false;
8240 }
8241
8242 18151 bool isCuttableNextType(int32_t type)
8243 {
8244
2/2
✓ Branch 0 taken 9830 times.
✓ Branch 1 taken 8321 times.
18151 switch(type)
8245 {
8246 case cSLASHNEXT:
8247 case cSLASHNEXTITEM:
8248 case cTALLGRASSNEXT:
8249 case cBUSHNEXT:
8250 case cSLASHNEXTTOUCHY:
8251 case cSLASHNEXTITEMTOUCHY:
8252 case cBUSHNEXTTOUCHY:
8253 8321 return true;
8254 }
8255
8256 9830 return false;
8257 18151 }
8258
8259 20007 bool isTouchyType(int32_t type)
8260 {
8261
2/2
✓ Branch 0 taken 8508 times.
✓ Branch 1 taken 11499 times.
20007 switch(type)
8262 {
8263 case cSLASHTOUCHY:
8264 case cSLASHITEMTOUCHY:
8265 case cBUSHTOUCHY:
8266 case cFLOWERSTOUCHY:
8267 case cTALLGRASSTOUCHY:
8268 case cSLASHNEXTTOUCHY:
8269 case cSLASHNEXTITEMTOUCHY:
8270 case cBUSHNEXTTOUCHY:
8271 11499 return true;
8272 }
8273
8274 8508 return false;
8275 20007 }
8276
8277 38846016 bool isCuttableType(int32_t type)
8278 {
8279
2/2
✓ Branch 0 taken 38392985 times.
✓ Branch 1 taken 453031 times.
38846016 switch(type)
8280 {
8281 case cSLASH:
8282 case cSLASHITEM:
8283 case cBUSH:
8284 case cFLOWERS:
8285 case cTALLGRASS:
8286 case cTALLGRASSNEXT:
8287 case cSLASHNEXT:
8288 case cSLASHNEXTITEM:
8289 case cBUSHNEXT:
8290
8291 case cSLASHTOUCHY:
8292 case cSLASHITEMTOUCHY:
8293 case cBUSHTOUCHY:
8294 case cFLOWERSTOUCHY:
8295 case cTALLGRASSTOUCHY:
8296 case cSLASHNEXTTOUCHY:
8297 case cSLASHNEXTITEMTOUCHY:
8298 case cBUSHNEXTTOUCHY:
8299 453031 return true;
8300 }
8301
8302 38392985 return false;
8303 38846016 }
8304
8305 19783 bool isCuttableItemType(int32_t type)
8306 {
8307
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 19331 times.
19783 switch(type)
8308 {
8309 case cSLASHITEM:
8310 case cBUSH:
8311 case cFLOWERS:
8312 case cTALLGRASS:
8313 case cTALLGRASSNEXT:
8314 case cSLASHNEXTITEM:
8315 case cBUSHNEXT:
8316
8317 case cSLASHITEMTOUCHY:
8318 case cBUSHTOUCHY:
8319 case cFLOWERSTOUCHY:
8320 case cTALLGRASSTOUCHY:
8321 case cSLASHNEXTITEMTOUCHY:
8322 case cBUSHNEXTTOUCHY:
8323 19331 return true;
8324 }
8325
8326 452 return false;
8327 19783 }
8328
8329 69 bool is_push(mapscr* m, int32_t pos)
8330 {
8331
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if(is_push_flag(m->sflag[pos]))
8332 return true;
8333 69 newcombo const& cmb = combobuf[m->data[pos]];
8334
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if(is_push_flag(cmb.flag))
8335 return true;
8336
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 55 times.
69 if(cmb.type == cPUSHBLOCK)
8337 14 return true;
8338
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
55 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8339 return true; //Counts as 'pushblock' flag
8340 55 return false;
8341 69 }
8342
8343 429 static std::map<int, screen_state_t> screen_states;
8344
8345 37503 std::map<int, screen_state_t>& get_screen_states()
8346 {
8347 37503 return screen_states;
8348 }
8349
8350 45762008 screen_state_t& get_screen_state(int screen)
8351 {
8352 45762008 return screen_states[screen];
8353 }
8354
8355 610 void clear_screen_states()
8356 {
8357 610 screen_states.clear();
8358 610 }
8359
8360 1597 void screen_item_set_state(int screen, ScreenItemState state)
8361 {
8362 1597 get_screen_state(screen).item_state = state;
8363 1597 }
8364
8365 557144 void mark_visited(int screen)
8366 {
8367
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 556669 times.
557144 if (screen < 0x80)
8368 {
8369
3/4
✓ Branch 0 taken 556669 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 459781 times.
✓ Branch 3 taken 96888 times.
556669 if(!get_qr(qr_ONLY_MARK_SCREENS_VISITED_IF_MAP_VIEWABLE) || (DMaps[cur_dmap].flags&dmfVIEWMAP))
8370 459781 game->maps[mapind(cur_map, screen)] |= mVISITED;
8371
8372 556669 markBmap(-1, screen);
8373 556669 }
8374 557144 }
8375